From: Jose E. Marchesi Date: Mon, 9 Sep 2019 10:13:23 +0000 (+0200) Subject: GCC port for eBPF X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=91dfef9610b8844c62dc7186a9aea9a6aca9805c;p=gcc.git GCC port for eBPF This patch series introduces a port of GCC to eBPF, which is a virtual machine that resides in the Linux kernel. Initially intended for user-level packet capture and filtering, eBPF is nowadays generalized to serve as a general-purpose infrastructure also for non-networking purposes. The binutils support is already upstream. See https://sourceware.org/ml/binutils/2019-05/msg00306.html. ChangeLog: * MAINTAINERS: Add myself as the maintainer of the eBPF port. Remove myself from Write After Approval section. * configure.ac: Support for bpf-*-* targets. * configure: Regenerate. contrib/ChangeLog: * config-list.mk (LIST): Disable go in bpf-*-* targets. gcc/ChangeLog: * doc/invoke.texi (Option Summary): Cover eBPF. (eBPF Options): New section. * doc/extend.texi (BPF Built-in Functions): Likewise. (BPF Kernel Helpers): Likewise. * config.gcc: Support for bpf-*-* targets. * common/config/bpf/bpf-common.c: New file. * config/bpf/t-bpf: Likewise. * config/bpf/predicates.md: Likewise. * config/bpf/constraints.md: Likewise. * config/bpf/bpf.opt: Likewise. * config/bpf/bpf.md: Likewise. * config/bpf/bpf.h: Likewise. * config/bpf/bpf.c: Likewise. * config/bpf/bpf-protos.h: Likewise. * config/bpf/bpf-opts.h: Likewise. * config/bpf/bpf-helpers.h: Likewise. * config/bpf/bpf-helpers.def: Likewise. gcc/testsuite/ChangeLog: * gcc.dg/builtins-config.h: eBPF doesn't support C99 standard functions. * gcc.c-torture/compile/20101217-1.c: Add a function prototype for printf. * gcc.c-torture/compile/20000211-1.c: Skip if target bpf-*-*. * gcc.c-torture/compile/poor.c: Likewise. * gcc.c-torture/compile/pr25311.c: Likewise. * gcc.c-torture/compile/pr39928-1.c: Likewise. * gcc.c-torture/compile/pr70061.c: Likewise. * gcc.c-torture/compile/920501-7.c: Likewise. * gcc.c-torture/compile/20000403-1.c: Likewise. * gcc.c-torture/compile/20001226-1.c: Likewise. * gcc.c-torture/compile/20030903-1.c: Likewise. * gcc.c-torture/compile/20031125-1.c: Likewise. * gcc.c-torture/compile/20040101-1.c: Likewise. * gcc.c-torture/compile/20040317-2.c: Likewise. * gcc.c-torture/compile/20040726-1.c: Likewise. * gcc.c-torture/compile/20051216-1.c: Likewise. * gcc.c-torture/compile/900313-1.c: Likewise. * gcc.c-torture/compile/920625-1.c: Likewise. * gcc.c-torture/compile/930421-1.c: Likewise. * gcc.c-torture/compile/930623-1.c: Likewise. * gcc.c-torture/compile/961004-1.c: Likewise. * gcc.c-torture/compile/980504-1.c: Likewise. * gcc.c-torture/compile/980816-1.c: Likewise. * gcc.c-torture/compile/990625-1.c: Likewise. * gcc.c-torture/compile/DFcmp.c: Likewise. * gcc.c-torture/compile/HIcmp.c: Likewise. * gcc.c-torture/compile/HIset.c: Likewise. * gcc.c-torture/compile/QIcmp.c: Likewise. * gcc.c-torture/compile/QIset.c: Likewise. * gcc.c-torture/compile/SFset.c: Likewise. * gcc.c-torture/compile/SIcmp.c: Likewise. * gcc.c-torture/compile/SIset.c: Likewise. * gcc.c-torture/compile/UHIcmp.c: Likewise. * gcc.c-torture/compile/UQIcmp.c: Likewise. * gcc.c-torture/compile/USIcmp.c: Likewise. * gcc.c-torture/compile/consec.c: Likewise. * gcc.c-torture/compile/limits-fndefn.c: Likewise. * gcc.c-torture/compile/lll.c: Likewise. * gcc.c-torture/compile/parms.c: Likewise. * gcc.c-torture/compile/pass.c: Likewise. * gcc.c-torture/compile/pp.c: Likewise. * gcc.c-torture/compile/pr32399.c: Likewise. * gcc.c-torture/compile/pr34091.c: Likewise. * gcc.c-torture/compile/pr34688.c: Likewise. * gcc.c-torture/compile/pr37258.c: Likewise. * gcc.c-torture/compile/pr37327.c: Likewise. * gcc.c-torture/compile/pr37381.c: Likewise. * gcc.c-torture/compile/pr37669-2.c: Likewise. * gcc.c-torture/compile/pr37669.c: Likewise. * gcc.c-torture/compile/pr37742-3.c: Likewise. * gcc.c-torture/compile/pr44063.c: Likewise. * gcc.c-torture/compile/pr48596.c: Likewise. * gcc.c-torture/compile/pr51856.c: Likewise. * gcc.c-torture/compile/pr54428.c: Likewise. * gcc.c-torture/compile/pr54713-1.c: Likewise. * gcc.c-torture/compile/pr54713-2.c: Likewise. * gcc.c-torture/compile/pr54713-3.c: Likewise. * gcc.c-torture/compile/pr55921.c: Likewise. * gcc.c-torture/compile/pr70240.c: Likewise. * gcc.c-torture/compile/pr70355.c: Likewise. * gcc.c-torture/compile/pr82052.c: Likewise. * gcc.c-torture/compile/pr83487.c: Likewise. * gcc.c-torture/compile/pr86122.c: Likewise. * gcc.c-torture/compile/pret-arg.c: Likewise. * gcc.c-torture/compile/regs-arg-size.c: Likewise. * gcc.c-torture/compile/structret.c: Likewise. * gcc.c-torture/compile/uuarg.c: Likewise. * gcc.dg/20001009-1.c: Likewise. * gcc.dg/20020418-1.c: Likewise. * gcc.dg/20020426-2.c: Likewise. * gcc.dg/20020430-1.c: Likewise. * gcc.dg/20040306-1.c: Likewise. * gcc.dg/20040622-2.c: Likewise. * gcc.dg/20050603-2.c: Likewise. * gcc.dg/20050629-1.c: Likewise. * gcc.dg/20061026.c: Likewise. * gcc.dg/Warray-bounds-3.c: Likewise. * gcc.dg/Warray-bounds-30.c: Likewise. * gcc.dg/Wframe-larger-than-2.c: Likewise. * gcc.dg/Wframe-larger-than.c: Likewise. * gcc.dg/Wrestrict-11.c: Likewise. * gcc.c-torture/compile/20000804-1.c: Likewise. * lib/target-supports.exp (check_effective_target_trampolines): Adapt to eBPF. (check_effective_target_indirect_jumps): Likewise. (check_effective_target_nonlocal_goto): Likewise. (check_effective_target_global_constructor): Likewise. (check_effective_target_return_address): Likewise. * gcc.target/bpf/bpf.exp: New file. * gcc.target/bpf/builtin-load.c: Likewise. * cc.target/bpf/constant-calls.c: Likewise. * gcc.target/bpf/diag-funargs.c: Likewise. * gcc.target/bpf/diag-funargs-2.c: Likewise. * gcc.target/bpf/diag-funargs-3.c: Likewise. * gcc.target/bpf/diag-indcalls.c: Likewise. * gcc.target/bpf/helper-bind.c: Likewise. * gcc.target/bpf/helper-bpf-redirect.c: Likewise. * gcc.target/bpf/helper-clone-redirect.c: Likewise. * gcc.target/bpf/helper-csum-diff.c: Likewise. * gcc.target/bpf/helper-csum-update.c: Likewise. * gcc.target/bpf/helper-current-task-under-cgroup.c: Likewise. * gcc.target/bpf/helper-fib-lookup.c: Likewise. * gcc.target/bpf/helper-get-cgroup-classid.c: Likewise. * gcc.target/bpf/helper-get-current-cgroup-id.c: Likewise. * gcc.target/bpf/helper-get-current-comm.c: Likewise. * gcc.target/bpf/helper-get-current-pid-tgid.c: Likewise. * gcc.target/bpf/helper-get-current-task.c: Likewise. * gcc.target/bpf/helper-get-current-uid-gid.c: Likewise. * gcc.target/bpf/helper-get-hash-recalc.c: Likewise. * gcc.target/bpf/helper-get-listener-sock.c: Likewise. * gcc.target/bpf/helper-get-local-storage.c: Likewise. * gcc.target/bpf/helper-get-numa-node-id.c: Likewise. * gcc.target/bpf/helper-get-prandom-u32.c: Likewise. * gcc.target/bpf/helper-get-route-realm.c: Likewise. * gcc.target/bpf/helper-get-smp-processor-id.c: Likewise. * gcc.target/bpf/helper-get-socket-cookie.c: Likewise. * gcc.target/bpf/helper-get-socket-uid.c: Likewise. * gcc.target/bpf/helper-getsockopt.c: Likewise. * gcc.target/bpf/helper-get-stack.c: Likewise. * gcc.target/bpf/helper-get-stackid.c: Likewise. * gcc.target/bpf/helper-ktime-get-ns.c: Likewise. * gcc.target/bpf/helper-l3-csum-replace.c: Likewise. * gcc.target/bpf/helper-l4-csum-replace.c: Likewise. * gcc.target/bpf/helper-lwt-push-encap.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-action.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-adjust-srh.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-store-bytes.c: Likewise. * gcc.target/bpf/helper-map-delete-elem.c: Likewise. * gcc.target/bpf/helper-map-lookup-elem.c: Likewise. * gcc.target/bpf/helper-map-peek-elem.c: Likewise. * gcc.target/bpf/helper-map-pop-elem.c: Likewise. * gcc.target/bpf/helper-map-push-elem.c: Likewise. * gcc.target/bpf/helper-map-update-elem.c: Likewise. * gcc.target/bpf/helper-msg-apply-bytes.c: Likewise. * gcc.target/bpf/helper-msg-cork-bytes.c: Likewise. * gcc.target/bpf/helper-msg-pop-data.c: Likewise. * gcc.target/bpf/helper-msg-pull-data.c: Likewise. * gcc.target/bpf/helper-msg-push-data.c: Likewise. * gcc.target/bpf/helper-msg-redirect-hash.c: Likewise. * gcc.target/bpf/helper-msg-redirect-map.c: Likewise. * gcc.target/bpf/helper-override-return.c: Likewise. * gcc.target/bpf/helper-perf-event-output.c: Likewise. * gcc.target/bpf/helper-perf-event-read.c: Likewise. * gcc.target/bpf/helper-perf-event-read-value.c: Likewise. * gcc.target/bpf/helper-perf-prog-read-value.c: Likewise. * gcc.target/bpf/helper-probe-read.c: Likewise. * gcc.target/bpf/helper-probe-read-str.c: Likewise. * gcc.target/bpf/helper-probe-write-user.c: Likewise. * gcc.target/bpf/helper-rc-keydown.c: Likewise. * gcc.target/bpf/helper-rc-pointer-rel.c: Likewise. * gcc.target/bpf/helper-rc-repeat.c: Likewise. * gcc.target/bpf/helper-redirect-map.c: Likewise. * gcc.target/bpf/helper-set-hash.c: Likewise. * gcc.target/bpf/helper-set-hash-invalid.c: Likewise. * gcc.target/bpf/helper-setsockopt.c: Likewise. * gcc.target/bpf/helper-skb-adjust-room.c: Likewise. * gcc.target/bpf/helper-skb-cgroup-id.c: Likewise. * gcc.target/bpf/helper-skb-change-head.c: Likewise. * gcc.target/bpf/helper-skb-change-proto.c: Likewise. * gcc.target/bpf/helper-skb-change-tail.c: Likewise. * gcc.target/bpf/helper-skb-change-type.c: Likewise. * gcc.target/bpf/helper-skb-ecn-set-ce.c: Likewise. * gcc.target/bpf/helper-skb-get-tunnel-key.c: Likewise. * gcc.target/bpf/helper-skb-get-tunnel-opt.c: Likewise. * gcc.target/bpf/helper-skb-get-xfrm-state.c: Likewise. * gcc.target/bpf/helper-skb-load-bytes.c: Likewise. * gcc.target/bpf/helper-skb-load-bytes-relative.c: Likewise. * gcc.target/bpf/helper-skb-pull-data.c: Likewise. * gcc.target/bpf/helper-skb-set-tunnel-key.c: Likewise. * gcc.target/bpf/helper-skb-set-tunnel-opt.c: Likewise. * gcc.target/bpf/helper-skb-store-bytes.c: Likewise. * gcc.target/bpf/helper-skb-under-cgroup.c: Likewise. * gcc.target/bpf/helper-skb-vlan-pop.c: Likewise. * gcc.target/bpf/helper-skb-vlan-push.c: Likewise. * gcc.target/bpf/helper-skc-lookup-tcp.c: Likewise. * gcc.target/bpf/helper-sk-fullsock.c: Likewise. * gcc.target/bpf/helper-sk-lookup-tcp.c: Likewise. * gcc.target/bpf/helper-sk-lookup-upd.c: Likewise. * gcc.target/bpf/helper-sk-redirect-hash.c: Likewise. * gcc.target/bpf/helper-sk-redirect-map.c: Likewise. * gcc.target/bpf/helper-sk-release.c: Likewise. * gcc.target/bpf/helper-sk-select-reuseport.c: Likewise. * gcc.target/bpf/helper-sk-storage-delete.c: Likewise. * gcc.target/bpf/helper-sk-storage-get.c: Likewise. * gcc.target/bpf/helper-sock-hash-update.c: Likewise. * gcc.target/bpf/helper-sock-map-update.c: Likewise. * gcc.target/bpf/helper-sock-ops-cb-flags-set.c: Likewise. * gcc.target/bpf/helper-spin-lock.c: Likewise. * gcc.target/bpf/helper-spin-unlock.c: Likewise. * gcc.target/bpf/helper-strtol.c: Likewise. * gcc.target/bpf/helper-strtoul.c: Likewise. * gcc.target/bpf/helper-sysctl-get-current-value.c: Likewise. * gcc.target/bpf/helper-sysctl-get-name.c: Likewise. * gcc.target/bpf/helper-sysctl-get-new-value.c: Likewise. * gcc.target/bpf/helper-sysctl-set-new-value.c: Likewise. * gcc.target/bpf/helper-tail-call.c: Likewise. * gcc.target/bpf/helper-tcp-check-syncookie.c: Likewise. * gcc.target/bpf/helper-tcp-sock.c: Likewise. * gcc.target/bpf/helper-trace-printk.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-head.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-meta.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-tail.c: Likewise. * gcc.target/bpf/skb-ancestor-cgroup-id.c: Likewise. * gcc.target/bpf/sync-fetch-and-add.c: Likewise. libgcc/ChangeLog: * config.host: Set cpu_type for bpf-*-* targets. * config/bpf/t-bpf: Likewise. * config/bpf/crtn.S: Likewise. * config/bpf/crti.S: New file. From-SVN: r275506 --- diff --git a/ChangeLog b/ChangeLog index f7913105e5c..3685a2472db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2019-09-09 Jose E. Marchesi + + * MAINTAINERS: Add myself as the maintainer of the eBPF port. + Remove myself from Write After Approval section. + +2019-09-09 Jose E. Marchesi + + * configure.ac: Support for bpf-*-* targets. + * configure: Regenerate. + 2019-09-09 Jose E. Marchesi * config.sub: Import upstream version 2019-06-30. diff --git a/MAINTAINERS b/MAINTAINERS index 109ac32e7ae..93c9bb4357d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -57,6 +57,7 @@ arm port Ramana Radhakrishnan arm port Kyrylo Tkachov avr port Denis Chertykov bfin port Jie Zhang +bpf port Jose E. Marchesi c6x port Bernd Schmidt cris port Hans-Peter Nilsson c-sky port Xianmiao Qu @@ -494,7 +495,6 @@ Luis Machado Ziga Mahkovec Matthew Malcomson Mikhail Maltsev -Jose E. Marchesi Patrick Marlier Simon Martin Alejandro Martinez diff --git a/configure b/configure index c3ec920df13..aec9186b2b0 100755 --- a/configure +++ b/configure @@ -3357,6 +3357,9 @@ case "${target}" in # No hosted I/O support. noconfigdirs="$noconfigdirs target-libssp" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libssp" + ;; powerpc-*-aix* | rs6000-*-aix*) noconfigdirs="$noconfigdirs target-libssp" ;; @@ -3391,12 +3394,43 @@ if test "${ENABLE_LIBSTDCXX}" = "default" ; then avr-*-*) noconfigdirs="$noconfigdirs target-libstdc++-v3" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libstdc++-v3" + ;; ft32-*-*) noconfigdirs="$noconfigdirs target-libstdc++-v3" ;; esac fi +# Disable C++ on systems where it is known to not work. +# For testing, you can override this with --enable-languages=c++. +case ,${enable_languages}, in + *,c++,*) + ;; + *) + case "${target}" in + bpf-*-*) + unsupported_languages="$unsupported_languages c++" + ;; + esac + ;; +esac + +# Disable Objc on systems where it is known to not work. +# For testing, you can override this with --enable-languages=objc. +case ,${enable_languages}, in + *,objc,*) + ;; + *) + case "${target}" in + bpf-*-*) + unsupported_languages="$unsupported_languages objc" + ;; + esac + ;; +esac + # Disable D on systems where it is known to not work. # For testing, you can override this with --enable-languages=d. case ,${enable_languages}, in @@ -3405,6 +3439,9 @@ case ,${enable_languages}, in *) case "${target}" in *-*-darwin*) + unsupported_languages="$unsupported_languages d" + ;; + bpf-*-*) unsupported_languages="$unsupported_languages d" ;; esac @@ -3437,6 +3474,9 @@ case "${target}" in # See . unsupported_languages="$unsupported_languages fortran" ;; + bpf-*-*) + unsupported_languages="$unsupported_languages fortran" + ;; esac # Disable libffi for some systems. @@ -3483,6 +3523,9 @@ case "${target}" in arm*-*-symbianelf*) noconfigdirs="$noconfigdirs target-libffi" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libffi" + ;; cris-*-* | crisv32-*-*) case "${target}" in *-*-linux*) @@ -3529,7 +3572,7 @@ esac # Disable the go frontend on systems where it is known to not work. Please keep # this in sync with contrib/config-list.mk. case "${target}" in -*-*-darwin* | *-*-cygwin* | *-*-mingw*) +*-*-darwin* | *-*-cygwin* | *-*-mingw* | bpf-* ) unsupported_languages="$unsupported_languages go" ;; esac @@ -3545,6 +3588,9 @@ if test x$enable_libgo = x; then *-*-cygwin* | *-*-mingw*) noconfigdirs="$noconfigdirs target-libgo" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libgo" + ;; esac fi @@ -3616,6 +3662,9 @@ case "${target}" in sparc-*-sunos4*) noconfigdirs="$noconfigdirs target-newlib target-libgloss" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-newlib target-libgloss" + ;; *-*-aix*) noconfigdirs="$noconfigdirs target-newlib target-libgloss" ;; @@ -3729,6 +3778,9 @@ case "${target}" in # newlib is not 64 bit ready noconfigdirs="$noconfigdirs target-newlib target-libgloss" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libobjc target-libbacktrace" + ;; sh*-*-pe|mips*-*-pe|*arm-wince-pe) noconfigdirs="$noconfigdirs tcl tk itcl libgui sim" ;; diff --git a/configure.ac b/configure.ac index 1fe97c001cc..b8ce2ad20b9 100644 --- a/configure.ac +++ b/configure.ac @@ -638,6 +638,9 @@ case "${target}" in # No hosted I/O support. noconfigdirs="$noconfigdirs target-libssp" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libssp" + ;; powerpc-*-aix* | rs6000-*-aix*) noconfigdirs="$noconfigdirs target-libssp" ;; @@ -672,12 +675,43 @@ if test "${ENABLE_LIBSTDCXX}" = "default" ; then avr-*-*) noconfigdirs="$noconfigdirs target-libstdc++-v3" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libstdc++-v3" + ;; ft32-*-*) noconfigdirs="$noconfigdirs target-libstdc++-v3" ;; esac fi +# Disable C++ on systems where it is known to not work. +# For testing, you can override this with --enable-languages=c++. +case ,${enable_languages}, in + *,c++,*) + ;; + *) + case "${target}" in + bpf-*-*) + unsupported_languages="$unsupported_languages c++" + ;; + esac + ;; +esac + +# Disable Objc on systems where it is known to not work. +# For testing, you can override this with --enable-languages=objc. +case ,${enable_languages}, in + *,objc,*) + ;; + *) + case "${target}" in + bpf-*-*) + unsupported_languages="$unsupported_languages objc" + ;; + esac + ;; +esac + # Disable D on systems where it is known to not work. # For testing, you can override this with --enable-languages=d. case ,${enable_languages}, in @@ -686,6 +720,9 @@ case ,${enable_languages}, in *) case "${target}" in *-*-darwin*) + unsupported_languages="$unsupported_languages d" + ;; + bpf-*-*) unsupported_languages="$unsupported_languages d" ;; esac @@ -715,6 +752,9 @@ case "${target}" in # See . unsupported_languages="$unsupported_languages fortran" ;; + bpf-*-*) + unsupported_languages="$unsupported_languages fortran" + ;; esac # Disable libffi for some systems. @@ -761,6 +801,9 @@ case "${target}" in arm*-*-symbianelf*) noconfigdirs="$noconfigdirs target-libffi" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libffi" + ;; cris-*-* | crisv32-*-*) case "${target}" in *-*-linux*) @@ -807,7 +850,7 @@ esac # Disable the go frontend on systems where it is known to not work. Please keep # this in sync with contrib/config-list.mk. case "${target}" in -*-*-darwin* | *-*-cygwin* | *-*-mingw*) +*-*-darwin* | *-*-cygwin* | *-*-mingw* | bpf-* ) unsupported_languages="$unsupported_languages go" ;; esac @@ -823,6 +866,9 @@ if test x$enable_libgo = x; then *-*-cygwin* | *-*-mingw*) noconfigdirs="$noconfigdirs target-libgo" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libgo" + ;; esac fi @@ -894,6 +940,9 @@ case "${target}" in sparc-*-sunos4*) noconfigdirs="$noconfigdirs target-newlib target-libgloss" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-newlib target-libgloss" + ;; *-*-aix*) noconfigdirs="$noconfigdirs target-newlib target-libgloss" ;; @@ -1007,6 +1056,9 @@ case "${target}" in # newlib is not 64 bit ready noconfigdirs="$noconfigdirs target-newlib target-libgloss" ;; + bpf-*-*) + noconfigdirs="$noconfigdirs target-libobjc target-libbacktrace" + ;; sh*-*-pe|mips*-*-pe|*arm-wince-pe) noconfigdirs="$noconfigdirs tcl tk itcl libgui sim" ;; diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 743fe00861f..0e473d63c22 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,7 @@ +2019-09-09 Jose E. Marchesi + + * config-list.mk (LIST): Disable go in bpf-*-* targets. + 2019-09-04 Martin Liska * mklog: Do not print changed functions for diff --git a/contrib/config-list.mk b/contrib/config-list.mk index 8c37cdb628c..a5f5d7bbd5a 100644 --- a/contrib/config-list.mk +++ b/contrib/config-list.mk @@ -40,6 +40,7 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \ arm-linux-androideabi arm-uclinux_eabi arm-eabi arm-rtems \ arm-symbianelf avr-elf \ bfin-elf bfin-uclinux bfin-linux-uclibc bfin-rtems bfin-openbsd \ + bpf-unknown-none \ c6x-elf c6x-uclinux cr16-elf cris-elf cris-linux crisv32-elf crisv32-linux \ csky-elf csky-linux-gnu \ epiphany-elf epiphany-elfOPT-with-stack-offset=16 fido-elf \ @@ -123,7 +124,7 @@ $(LIST): make-log-dir TGT=`echo $@ | awk 'BEGIN { FS = "OPT" }; { print $$1 }'` && \ TGT=`$(GCC_SRC_DIR)/config.sub $$TGT` && \ case $$TGT in \ - *-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix*) \ + *-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix* | bpf-*-*) \ ADDITIONAL_LANGUAGES=""; \ ;; \ *) \ diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb28809b556..34b2f620b8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2019-09-09 Jose E. Marchesi + + * doc/invoke.texi (Option Summary): Cover eBPF. + (eBPF Options): New section. + * doc/extend.texi (BPF Built-in Functions): Likewise. + (BPF Kernel Helpers): Likewise. + +2019-09-09 Jose E. Marchesi + + * config.gcc: Support for bpf-*-* targets. + * common/config/bpf/bpf-common.c: New file. + * config/bpf/t-bpf: Likewise. + * config/bpf/predicates.md: Likewise. + * config/bpf/constraints.md: Likewise. + * config/bpf/bpf.opt: Likewise. + * config/bpf/bpf.md: Likewise. + * config/bpf/bpf.h: Likewise. + * config/bpf/bpf.c: Likewise. + * config/bpf/bpf-protos.h: Likewise. + * config/bpf/bpf-opts.h: Likewise. + * config/bpf/bpf-helpers.h: Likewise. + * config/bpf/bpf-helpers.def: Likewise. + 2019-09-09 Jose E. Marchesi * doc/sourcebuild.texi (Effective-Target Keywords): Document diff --git a/gcc/common/config/bpf/bpf-common.c b/gcc/common/config/bpf/bpf-common.c new file mode 100644 index 00000000000..0d04f21b8f9 --- /dev/null +++ b/gcc/common/config/bpf/bpf-common.c @@ -0,0 +1,55 @@ +/* Common hooks for eBPF. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "config/bpf/bpf-protos.h" + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS 0 + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options bpf_option_optimization_table[] = + { + /* Enable -funroll-all-loops by default. */ + { OPT_LEVELS_ALL, OPT_funroll_all_loops, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE bpf_option_optimization_table + +/* Implement TARGET_OPTION_DEFAULT_PARAMS. */ + +static void +bpf_option_default_params (void) +{ + /* XXX large-stack-frame = 512 bytes */ + /* XXX max-unrolled-insns */ + /* XXX max-unroll-times */ +} + +#undef TARGET_OPTION_DEFAULT_PARAMS +#define TARGET_OPTION_DEFAULT_PARAMS bpf_option_default_params + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/config.gcc b/gcc/config.gcc index 94a36083db0..0eba7ca1d4d 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -360,6 +360,9 @@ avr-*-*) bfin*-*) cpu_type=bfin ;; +bpf-*-*) + cpu_type=bpf + ;; crisv32-*) cpu_type=cris ;; @@ -1308,6 +1311,12 @@ bfin*-*) use_collect2=no use_gcc_stdint=wrap ;; +bpf-*-*) + tmake_file="${tmake_file} bpf/t-bpf" + use_collect2=no + extra_headers="bpf-helpers.h" + use_gcc_stdint=provide + ;; cr16-*-elf) tm_file="elfos.h ${tm_file} newlib-stdint.h" tmake_file="${tmake_file} cr16/t-cr16 " diff --git a/gcc/config/bpf/bpf-helpers.def b/gcc/config/bpf/bpf-helpers.def new file mode 100644 index 00000000000..cd0640297d0 --- /dev/null +++ b/gcc/config/bpf/bpf-helpers.def @@ -0,0 +1,194 @@ +/* Kernel helpers database. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* This file contains the definition of the kernel helpers that are + available to eBPF programs. + + The primary source for information on kernel helpers is the + linux/include/uapi/linux/bpf.h file in the Linux source tree. + Please keep this database in sync. + + The first column is the first kernel version featuring the helper + function. This should be an enumerate from bpf_kernel_version, + defined in bpf-opts.h. Note that the backend assumes that helpers + never get deprecated in the kernel. If that eventually happens, + then we will need to use a bitmask here instead of an enumerate. + + The second column is the constant-name for the helper. + The third column is the program-name of the helper. + + The fourth column is a list of names describing the types of the + values returned and accepted by the helper, in one of these forms: + + TYPES (type1, type2, ..., 0) + VTYPES (type1, type2, ..., 0) + + VTYPES should be used should the helper accept a variable number of + arguments, TYPES otherwise. The valid type names are: + + `vt' for void. + `it' for signed int. + `ut' for unsigned int. + `pt' for void*. + `cpt' for const void*. + `st' for short int. + `ust' for unsigned short int. + `cst' for const char *. + `ullt' for unsigned long long. + `llt' for long long. + `u32t' for uint32. + `u64t' for uint64. + + In types descriptions, the firt entry corresponds to the value + returned by the helper. Subsequent names correspond to the helper + arguments. Finally, a 0 should close the list. + + VERY IMPORTANT: the helper entries should be listed in the same + order than in the definition of __BPF_FUNC_MAPPER in + linux/include/uapi/linux/bpf.h! */ + +DEF_HELPER (LINUX_V4_0, MAP_LOOKUP_ELEM, map_lookup_elem, TYPES (pt, pt, pt, 0)) +DEF_HELPER (LINUX_V4_0, MAP_UPDATE_ELEM, map_update_elem, TYPES (it, pt, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_0, MAP_DELETE_ELEM, map_delete_elem, TYPES (it, pt, pt, 0)) +DEF_HELPER (LINUX_V4_1, PROBE_READ, probe_read, TYPES (it, pt, ut, cpt, 0)) +DEF_HELPER (LINUX_V4_1, KTIME_GET_NS, ktime_get_ns, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_1, TRACE_PRINTK, trace_printk, VTYPES (it, cst, it, 0)) +DEF_HELPER (LINUX_V4_1, GET_PRANDOM_U32, get_prandom_u32, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_1, GET_SMP_PROCESSOR_ID, get_smp_processor_id, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_1, SKB_STORE_BYTES, skb_store_bytes, TYPES (it, pt, it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_1, L3_CSUM_REPLACE, l3_csum_replace, TYPES (it, pt, it, it ,it ,it, 0)) +DEF_HELPER (LINUX_V4_1, L4_CSUM_REPLACE, l4_csum_replace, TYPES (it, pt, it, it, it, it, 0)) +DEF_HELPER (LINUX_V4_2, TAIL_CALL, tail_call, TYPES (vt, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_2, CLONE_REDIRECT, clone_redirect, TYPES (it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_2, GET_CURRENT_PID_TGID, get_current_pid_tgid, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_2, GET_CURRENT_UID_GID, get_current_uid_gid, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_2, GET_CURRENT_COMM, get_current_comm, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_3, GET_CGROUP_CLASSID, get_cgroup_classid, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_3, SKB_VLAN_PUSH, skb_vlan_push, TYPES (it, pt, st, ust, 0)) +DEF_HELPER (LINUX_V4_3, SKB_VLAN_POP, skb_vlan_pop, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_3, SKB_GET_TUNNEL_KEY, skb_get_tunnel_key, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_3, SKB_SET_TUNNEL_KEY, skb_set_tunnel_key, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_3, PERF_EVENT_READ, perf_event_read, TYPES (ullt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_4, REDIRECT, redirect, TYPES (it, it, it, 0)) +DEF_HELPER (LINUX_V4_4, GET_ROUTE_REALM, get_route_realm, TYPES (ut, pt, 0)) +DEF_HELPER (LINUX_V4_4, PERF_EVENT_OUTPUT, perf_event_output, \ + TYPES (it, pt, pt, ullt, pt, it, 0)) +DEF_HELPER (LINUX_V4_5, SKB_LOAD_BYTES, skb_load_bytes, TYPES (it, pt, it, pt, it, 0)) +DEF_HELPER (LINUX_V4_6, GET_STACKID, get_stackid, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_6, CSUM_DIFF, csum_diff, TYPES (it, pt, it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_6, SKB_GET_TUNNEL_OPT, skb_get_tunnel_opt, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_6, SKB_SET_TUNNEL_OPT, skb_set_tunnel_opt, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_8, SKB_CHANGE_PROTO, skb_change_proto, TYPES (it, pt, st, u64t, 0)) +DEF_HELPER (LINUX_V4_8, SKB_CHANGE_TYPE, skb_change_type, TYPES (it, pt, u32t, 0)) +DEF_HELPER (LINUX_V4_8, SKB_UNDER_CGROUP, skb_under_cgroup, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_8, GET_HASH_RECALC, get_hash_recalc, TYPES (ut, pt, 0)) +DEF_HELPER (LINUX_V4_8, GET_CURRENT_TASK, get_current_task, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_8, PROBE_WRITE_USER, probe_write_user, TYPES (it, pt, cpt, ut, 0)) +DEF_HELPER (LINUX_V4_9, CURRENT_TASK_UNDER_CGROUP, current_task_under_cgroup, \ + TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_9, SKB_CHANGE_TAIL, skb_change_tail, TYPES (it, pt, ut, u64t, 0)) +DEF_HELPER (LINUX_V4_9, SKB_PULL_DATA, skb_pull_data, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_9, CSUM_UPDATE, csum_update, TYPES (llt, pt, u32t, 0)) +DEF_HELPER (LINUX_V4_9, SET_HASH_INVALID, set_hash_invalid, TYPES (vt, pt, 0)) +DEF_HELPER (LINUX_V4_10, GET_NUMA_NODE_ID, get_numa_node_id, TYPES (it, 0)) +DEF_HELPER (LINUX_V4_10, SKB_CHANGE_HEAD, skb_change_head, TYPES (it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_10, XDP_ADJUST_HEAD, xdp_adjust_head, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_11, PROBE_READ_STR, probe_read_str, TYPES (it, pt, u32t, cpt, 0)) +DEF_HELPER (LINUX_V4_12, GET_SOCKET_COOKIE, get_socket_cookie, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_12, GET_SOCKET_UID, get_socket_uid, TYPES (ut, pt, 0)) +DEF_HELPER (LINUX_V4_13, SET_HASH, set_hash, TYPES (ut, pt, u32t, 0)) +DEF_HELPER (LINUX_V4_13, SETSOCKOPT, setsockopt, TYPES (it, pt, it, it, pt, it, 0)) +DEF_HELPER (LINUX_V4_13, SKB_ADJUST_ROOM, skb_adjust_room, TYPES (it, pt, st, u32t, ullt, 0)) +DEF_HELPER (LINUX_V4_14, REDIRECT_MAP, redirect_map, TYPES (it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_14, SK_REDIRECT_MAP, sk_redirect_map, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_14, SOCK_MAP_UPDATE, sock_map_update, TYPES (it, pt, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_15, XDP_ADJUST_META, xdp_adjust_meta, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_15, PERF_EVENT_READ_VALUE, perf_event_read_value, + TYPES (it, pt, ullt, pt, ut, 0)) +DEF_HELPER (LINUX_V4_15, PERF_PROG_READ_VALUE, perf_prog_read_value, + TYPES (it, pt, pt, ut, 0)) +DEF_HELPER (LINUX_V4_15, GETSOCKOPT, getsockopt, TYPES (it, pt, it, it, pt, it, 0)) + +DEF_HELPER (LINUX_V4_16, OVERRIDE_RETURN, override_return, TYPES (it, pt, ult, 0)) +DEF_HELPER (LINUX_V4_16, SOCK_OPS_CB_FLAGS_SET, sock_ops_cb_flags_set, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_17, MSG_REDIRECT_MAP, msg_redirect_map, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_17, MSG_APPLY_BYTES, msg_apply_bytes, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_17, MSG_CORK_BYTES, msg_cork_bytes, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_17, MSG_PULL_DATA, msg_pull_data, TYPES (it, pt, it, it, it, 0)) +DEF_HELPER (LINUX_V4_17, BIND, bind, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_18, XDP_ADJUST_TAIL, xdp_adjust_tail, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_18, SKB_GET_XFRM_STATE, + skb_get_xfrm_state, TYPES (it, pt, it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_18, GET_STACK, get_stack, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_18, SKB_LOAD_BYTES_RELATIVE, skb_load_bytes_relative, + TYPES (it, pt, it, pt, it, ut, 0)) +DEF_HELPER (LINUX_V4_18, FIB_LOOKUP, fib_lookup, TYPES (it, pt, pt, it, ut, 0)) +DEF_HELPER (LINUX_V4_18, SOCK_HASH_UPDATE, sock_hash_update, TYPES (it, pt, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_18, MSG_REDIRECT_HASH, msg_redirect_hash, TYPES (it, pt, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_18, SK_REDIRECT_HASH, sk_redirect_hash, TYPES (it, pt, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_18, LWT_PUSH_ENCAP, lwt_push_encap, TYPES (it, pt, ut, pt, ut, 0)) +DEF_HELPER (LINUX_V4_18, LWT_SEG6_STORE_BYTES, lwt_seg6_store_bytes, + TYPES (it, pt, ut, pt, ut, 0)) +DEF_HELPER (LINUX_V4_18, LWT_SEG6_ADJUST_SRH, lwt_seg6_adjust_srh, TYPES (it, pt, ut, ut, 0)) +DEF_HELPER (LINUX_V4_18, LWT_SEG6_ACTION, lwt_seg6_action, TYPES (it, pt, ut, pt, ut, 0)) +DEF_HELPER (LINUX_V4_18, RC_REPEAT, rc_repeat, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_18, RC_KEYDOWN, rc_keydown, TYPES (it, pt, ut, ullt, ut, 0)) +DEF_HELPER (LINUX_V4_18, SKB_CGROUP_ID, skb_cgroup_id, TYPES (ullt, pt, 0)) +DEF_HELPER (LINUX_V4_18, GET_CURRENT_CGROUP_ID, get_current_cgroup_id, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_19, GET_LOCAL_STORAGE, get_local_storage, TYPES (pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_19, SK_SELECT_REUSEPORT, sk_select_reuseport, + TYPES (it, pt, pt, pt, ut, 0)) +DEF_HELPER (LINUX_V4_19, SKB_ANCESTOR_CGROUP_ID, skb_ancestor_cgroup_id, + TYPES (ullt, pt, it, 0)) +DEF_HELPER (LINUX_V4_20, SK_LOOKUP_TCP, sk_lookup_tcp, TYPES (pt, pt, pt, it, ullt, ullt, 0)) +DEF_HELPER (LINUX_V4_20, SK_LOOKUP_UDP, sk_lookup_udp, TYPES (pt, pt, pt, it, ullt, ullt, 0)) +DEF_HELPER (LINUX_V4_20, SK_RELEASE, sk_release, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_20, MAP_PUSH_ELEM, map_push_elem, TYPES (it, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_20, MAP_POP_ELEM, map_pop_elem, TYPES (it, pt, pt, 0)) +DEF_HELPER (LINUX_V4_20, MAP_PEEK_ELEM, map_peek_elem, TYPES (it, pt, pt, 0)) +DEF_HELPER (LINUX_V4_20, MSG_PUSH_DATA, msg_push_data, TYPES (it, pt, it, it, it, 0)) +DEF_HELPER (LINUX_V5_0, MSG_POP_DATA, msg_pop_data, TYPES (it, pt, it, it, it, 0)) +DEF_HELPER (LINUX_V5_0, RC_POINTER_REL, rc_pointer_rel, TYPES (it, pt, it, it, 0)) +DEF_HELPER (LINUX_V5_1, SPIN_LOCK, spin_lock, TYPES (vt, pt, 0)) +DEF_HELPER (LINUX_V5_1, SPIN_UNLOCK, spin_unlock, TYPES (vt, pt, 0)) +DEF_HELPER (LINUX_V5_1, SK_FULLSOCK, sk_fullsock, TYPES (pt, pt, 0)) +DEF_HELPER (LINUX_V5_1, TCP_SOCK, tcp_sock, TYPES (pt, pt, 0)) +DEF_HELPER (LINUX_V5_1, SKB_ECN_SET_CE, skb_ecn_set_ce, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V5_1, GET_LISTENER_SOCK, get_listener_sock, TYPES (pt, pt, 0)) +DEF_HELPER (LINUX_V5_2, SKC_LOOKUP_TCP, skc_lookup_tcp, + TYPES (pt, pt, pt, u32t, u64t, u64t, 0)) +DEF_HELPER (LINUX_V5_2, TCP_CHECK_SYNCOOKIE, tcp_check_syncookie, + TYPES (it, pt, pt, u32t, pt, u32t, 0)) +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_NAME, sysctl_get_name, TYPES (it, pt, pt, ullt, u64t, 0)) +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_CURRENT_VALUE, sysctl_get_current_value, + TYPES (it, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_NEW_VALUE, sysctl_get_new_value, + TYPES (it, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V5_2, SYSCTL_SET_NEW_VALUE, sysctl_set_new_value, + TYPES (it, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V5_2, STRTOL, strtol, TYPES (it, cst, ullt, u64t, pt, 0)) +DEF_HELPER (LINUX_V5_2, STRTOUL, strtoul, TYPES (it, pt, ullt, u64t, pt, 0)) +DEF_HELPER (LINUX_V5_2, SK_STORAGE_GET, sk_storage_get, TYPES (pt, pt, pt, pt, u64t, 0)) +DEF_HELPER (LINUX_V5_2, SK_STORAGE_DELETE, sk_storage_delete, TYPES (it, pt, pt, 0)) + +/* +Local variables: +mode:c +End: +*/ diff --git a/gcc/config/bpf/bpf-helpers.h b/gcc/config/bpf/bpf-helpers.h new file mode 100644 index 00000000000..14275439446 --- /dev/null +++ b/gcc/config/bpf/bpf-helpers.h @@ -0,0 +1,327 @@ +/* Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* The purpose of this file is to provide a compatiblity layer with + the Linux kernel bpf_helpers.h header that is located in + linux/tools/testing/selftests/bpf/bpf_helpers.h. That file is + currently llvm-specific. */ + +#ifndef __BPF_HELPERS_H +#define __BPF_HELPERS_H + +#define SEC(NAME) __attribute__((section(NAME), used)) + +/* Flags used in some kernel helpers. */ + +#define BPF_ANY 0 +#define BPF_NOEXIST 1 +#define BPF_EXIST 2 + +#define BPF_F_LOCK 4 +#define BPF_F_NO_COMMON_LRU (1U << 1) +#define BPF_F_NUMA_NODE (1U << 2) + +/* Functions to call kernel helpers. We provide the "standard" bpf_* + names as synonyms of the corresponding GCC builtins. In some + cases, where non-void pointers are passed to the helper, inline + functions are used to achieve proper type checking. */ + +#ifndef KERNEL_VERSION +# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,0,0) + +#define bpf_map_lookup_elem __builtin_bpf_helper_map_lookup_elem +#define bpf_map_update_elem __builtin_bpf_helper_map_update_elem +#define bpf_map_delete_elem __builtin_bpf_helper_map_delete_elem + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,1,0) + +#define bpf_probe_read __builtin_bpf_helper_probe_read +#define bpf_ktime_get_ns __builtin_bpf_helper_ktime_get_ns +#define bpf_trace_printk __builtin_bpf_helper_trace_printk +#define bpf_get_prandom_u32 __builtin_bpf_helper_get_prandom_u32 +#define bpf_get_smp_processor_id __builtin_bpf_helper_get_smp_processor_id +#define bpf_skb_store_bytes __builtin_bpf_helper_skb_store_bytes +#define bpf_l3_csum_replace __builtin_bpf_helper_l3_csum_replace +#define bpf_l4_csum_replace __builtin_bpf_helper_l4_csum_replace + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,2,0) + +#define bpf_tail_call __builtin_bpf_helper_tail_call +#define bpf_clone_redirect __builtin_bpf_helper_clone_redirect +#define bpf_get_current_pid_tgid __builtin_bpf_helper_get_current_pid_tgid +#define bpf_get_current_uid_gid __builtin_bpf_helper_get_current_uid_gid +#define bpf_get_current_comm __builtin_bpf_helper_get_current_comm + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,3,0) + +#define bpf_get_cgroup_classid __builtin_bpf_helper_get_cgroup_classid +#define bpf_skb_vlan_push __builtin_bpf_helper_skb_vlan_push +#define bpf_skb_vlan_pop __builtin_bpf_helper_skb_vlan_pop +#define bpf_skb_get_tunnel_key __builtin_bpf_helper_skb_get_tunnel_key +#define bpf_skb_set_tunnel_key __builtin_bpf_helper_skb_set_tunnel_key +#define bpf_perf_event_read __builtin_bpf_helper_perf_event_read + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,4,0) + +#define bpf_redirect __builtin_bpf_helper_redirect +#define bpf_get_route_realm __builtin_bpf_helper_get_route_realm +#define bpf_perf_event_output __builtin_bpf_helper_perf_event_output + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,5,0) + +#define bpf_skb_load_bytes __builtin_bpf_helper_skb_load_bytes + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,6,0) + +#define bpf_get_stackid __builtin_bpf_helper_get_stackid +#define bpf_csum_diff __builtin_bpf_helper_csum_diff +#define bpf_skb_get_tunnel_opt __builtin_bpf_helper_skb_get_tunnel_opt +#define bpf_skb_set_tunnel_opt __builtin_bpf_helper_skb_set_tunnel_opt + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,8,0) + +#define bpf_skb_change_proto __builtin_bpf_helper_skb_change_proto +#define bpf_skb_change_type __builtin_bpf_helper_skb_change_type +#define bpf_skb_under_cgroup __builtin_bpf_helper_skb_under_cgroup +#define bpf_get_hash_recalc __builtin_bpf_helper_get_hash_recalc +#define bpf_get_current_task __builtin_bpf_helper_get_current_task +#define bpf_probe_write_user __builtin_bpf_helper_probe_write_user + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,9,0) + +#define bpf_current_task_under_cgroup __builtin_bpf_helper_current_task_under_cgroup +#define bpf_skb_change_tail __builtin_bpf_helper_skb_change_tail +#define bpf_skb_pull_data __builtin_bpf_helper_skb_pull_data +#define bpf_csum_update __builtin_bpf_helper_csum_update +#define bpf_set_hash_invalid __builtin_bpf_helper_set_hash_invalid + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,10,0) + +#define bpf_get_numa_node_id __builtin_bpf_helper_get_numa_node_id +#define bpf_skb_change_head __builtin_bpf_helper_skb_change_head +#define bpf_xdp_adjust_head __builtin_bpf_helper_xdp_adjust_head + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,11,0) + +#define bpf_probe_read_str __builtin_bpf_helper_probe_read_str + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,12,0) + +#define bpf_get_socket_cookie __builtin_bpf_helper_get_socket_cookie +#define bpf_get_socket_uid __builtin_bpf_helper_get_socket_uid + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,13,0) + +#define bpf_set_hash __builtin_bpf_helper_set_hash +#define bpf_setsockopt __builtin_bpf_helper_setsockopt +#define bpf_skb_adjust_room __builtin_bpf_helper_skb_adjust_room + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,14,0) + +#define bpf_redirect_map __builtin_bpf_helper_redirect_map +#define bpf_sk_redirect_map __builtin_bpf_helper_sk_redirect_map +#define bpf_sock_map_update __builtin_bpf_helper_sock_map_update + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,15,0) + +#define bpf_perf_event_read_value __builtin_bpf_helper_perf_event_read_value +#define bpf_perf_prog_read_value __builtin_bpf_helper_perf_prog_read_value +#define bpf_getsockopt __builtin_bpf_helper_getsockopt +#define bpf_xdp_adjust_meta __builtin_bpf_helper_xdp_adjust_meta + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,16,0) + +#define bpf_override_return __builtin_bpf_helper_override_return +#define bpf_sock_ops_cb_flags_set __builtin_bpf_helper_sock_ops_cb_flags_set + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,17,0) + +#define bpf_msg_redirect_map __builtin_bpf_helper_msg_redirect_map +#define bpf_msg_apply_bytes __builtin_bpf_helper_msg_apply_bytes +#define bpf_msg_cork_bytes __builtin_bpf_helper_msg_cork_bytes +#define bpf_pull_data __builtin_bpf_helper_pull_data +#define bpf_bind __builtin_bpf_helper_bpf_bind + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,18,0) + +#define bpf_xdp_adjust_tail __builtin_bpf_helper_xdp_adjust_tail +#define bpf_skb_get_xfrm_state __builtin_bpf_helper_skb_get_xfrm_state +#define bpf_get_stack __builtin_bpf_helper_get_stack +#define bpf_skb_load_bytes_relative __builtin_bpf_helper_skb_load_bytes_relative +#define bpf_sock_hash_update __builtin_bpf_helper_sock_hash_update +#define bpf_msg_redirect_hash __builtin_bpf_helper_msg_redirect_hash +#define bpf_sk_redirect_hash __builtin_bpf_helper_sk_redirect_hash +#define bpf_lwt_push_encap __builtin_bpf_helper_lwt_push_encap +#define bpf_lwt_seg6_store_bytes __builtin_bpf_helper_lwt_seg6_store_bytes +#define bpf_lwt_seg6_adjust_srh __builtin_bpf_helper_lwt_seg6_adjust_srh +#define bpf_lwt_seg6_action __builtin_bpf_helper_lwt_seg6_action +#define bpf_rc_repeat __builtin_bpf_helper_rc_repeat +#define bpf_rc_keydown __builtin_bpf_helper_rc_keydown +#define bpf_skb_cgroup_id __builtin_bpf_helper_skb_cgroup_id +#define bpf_get_current_cgroup_id __builtin_bpf_helper_get_current_cgroup_id + +static inline int +bpf_fib_lookup (void *ctx, struct bpf_fib_lookup *param, int plen, + unsigned int flags) +{ + return __builtin_bpf_helper_fib_lookup (ctx, (void *) param, plen, flags); +} + + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,19,0) + +#define bpf_get_local_storage __builtin_bpf_helper_get_local_storage +#define bpf_sk_select_reuseport __builtin_bpf_helper_sk_select_reuseport +#define bpf_skb_ancestor_cgroup_id __builtin_bpf_helper_skb_ancestor_cgroup_id + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,20,0) + +#define bpf_sk_release __builtin_bpf_helper_sk_release +#define bpf_map_push_elem __builtin_bpf_helper_map_push_elem +#define bpf_map_pop_elem __builtin_bpf_helper_map_pop_elem +#define bpf_map_peek_elem __builtin_bpf_helper_map_peek_elem +#define bpf_msg_push_data __builtin_bpf_helper_msg_push_data + +static inline struct bpf_sock * +bpf_sk_lookup_tcp (void *ctx, struct bpf_sock_tuple *tuple, + int size, unsigned long long netns_id, + unsigned long long flags) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_sk_lookup_tcp (ctx, + (void *) tuple, + size, + netns_id, flags); +} + +static inline struct bpf_sock * +bpf_sk_lookup_udp (void *ctx, struct bpf_sock_tuple *tuple, + int size, unsigned long long netns_id, + unsigned long long flags) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_sk_lookup_udp (ctx, + (void *) tuple, + size, + netns_id, flags); +} + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (5,0,0) + +#define bpf_msg_pop_data __builtin_bpf_helper_pop_data +#define bpf_rc_pointer_rel __builtin_bpf_helper_rc_pointer_rel + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (5,1,0) + +#define bpf_spin_lock __builtin_bpf_helper_spin_lock +#define bpf_spin_unlock __builtin_bpf_helper_spin_unlock +#define bpf_skb_ecn_set_ce __builtin_bpf_helper_skb_ecn_set_ce + +static inline struct bpf_sock * +bpf_sk_fullsock (struct bpf_sock *sk) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_sk_fullsock ((void *) sk); +} + +static inline struct bpf_sock * +bpf_tcp_sock (struct bpf_sock *sk) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_tcp_sock ((void *) sk); +} + +static inline struct bpf_sock * +bpf_get_listener_sock (struct bpf_sock *sk) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_get_listener_sock ((void *) sk); +} + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (5,2,0) + + +#endif /* 5.2 */ +#endif /* 5.1 */ +#endif /* 5.0 */ +#endif /* 4.20 */ +#endif /* 4.19 */ +#endif /* 4.18 */ +#endif /* 4.17 */ +#endif /* 4.16 */ +#endif /* 4.15 */ +#endif /* 4.14 */ +#endif /* 4.13 */ +#endif /* 4.12 */ +#endif /* 4.11 */ +#endif /* 4.10 */ +#endif /* 4.9 */ +#endif /* 4.8 */ +#endif /* 4.6 */ +#endif /* 4.5 */ +#endif /* 4.4 */ +#endif /* 4.3 */ +#endif /* 4.2 */ +#endif /* 4.1 */ +#endif /* 4.0 */ + +/* Functions to emit BPF_LD_ABS and BPF_LD_IND instructions. We + provide the "standard" names as synonyms of the corresponding GCC + builtins. Note how the SKB argument is ignored. */ + +static inline long long +load_byte (void *skb __attribute__ ((unused)), + unsigned long long off) +{ + return __builtin_bpf_load_byte (off); +} + +static inline long long +load_half (void *skb __attribute__ ((unused)), + unsigned long long off) +{ + return __builtin_bpf_load_half (off); +} + +static inline long long +load_word (void *skb __attribute__ ((unused)), + unsigned long long off) +{ + return __builtin_bpf_load_word (off); +} + +struct bpf_map_def +{ + unsigned int type; + unsigned int key_size; + unsigned int value_size; + unsigned int max_entries; + unsigned int map_flags; + unsigned int inner_map_idx; + unsigned int numa_node; +}; + +#endif /* ! __BPF_HELPERS_H */ diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h new file mode 100644 index 00000000000..9f210a19c4a --- /dev/null +++ b/gcc/config/bpf/bpf-opts.h @@ -0,0 +1,56 @@ +/* Definitions for option handling for eBPF. + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#ifndef BPF_OPTS_H +#define BPF_OPTS_H + +/* Supported versions of the Linux kernel. */ +enum bpf_kernel_version +{ + /* Linux 4.x */ + LINUX_V4_0, + LINUX_V4_1, + LINUX_V4_2, + LINUX_V4_3, + LINUX_V4_4, + LINUX_V4_5, + LINUX_V4_6, + LINUX_V4_7, + LINUX_V4_8, + LINUX_V4_9, + LINUX_V4_10, + LINUX_V4_11, + LINUX_V4_12, + LINUX_V4_13, + LINUX_V4_14, + LINUX_V4_15, + LINUX_V4_16, + LINUX_V4_17, + LINUX_V4_18, + LINUX_V4_19, + LINUX_V4_20, + /* Linux 5.x */ + LINUX_V5_0, + LINUX_V5_1, + LINUX_V5_2, + LINUX_LATEST = LINUX_V5_2, + LINUX_NATIVE, +}; + +#endif /* ! BPF_OPTS_H */ diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h new file mode 100644 index 00000000000..3a835f4f12e --- /dev/null +++ b/gcc/config/bpf/bpf-protos.h @@ -0,0 +1,33 @@ +/* Definition of eBPF target for GNU compiler. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_BPF_PROTOS_H +#define GCC_BPF_PROTOS_H + +/* Routines implemented in bpf.c. */ + +extern HOST_WIDE_INT bpf_initial_elimination_offset (int, int); +extern const char *bpf_output_call (rtx); +extern void bpf_target_macros (cpp_reader *); +extern void bpf_print_operand (FILE *, rtx, int); +extern void bpf_print_operand_address (FILE *, rtx); +extern void bpf_expand_prologue (void); +extern void bpf_expand_epilogue (void); + +#endif /* ! GCC_BPF_PROTOS_H */ diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c new file mode 100644 index 00000000000..8b2a59273fe --- /dev/null +++ b/gcc/config/bpf/bpf.c @@ -0,0 +1,948 @@ +/* Subroutines used for code generation for eBPF. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#define IN_TARGET_CODE 1 + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "regs.h" +#include "insn-config.h" +#include "insn-attr.h" +#include "recog.h" +#include "output.h" +#include "alias.h" +#include "tree.h" +#include "stringpool.h" +#include "attribs.h" +#include "varasm.h" +#include "stor-layout.h" +#include "calls.h" +#include "function.h" +#include "explow.h" +#include "memmodel.h" +#include "emit-rtl.h" +#include "reload.h" +#include "tm_p.h" +#include "target.h" +#include "target-def.h" +#include "basic-block.h" +#include "expr.h" +#include "optabs.h" +#include "bitmap.h" +#include "df.h" +#include "c-family/c-common.h" +#include "diagnostic.h" +#include "builtins.h" +#include "predict.h" +#include "langhooks.h" + +/* Per-function machine data. */ +struct GTY(()) machine_function +{ + /* Number of bytes saved on the stack for local variables. */ + int local_vars_size; + + /* Number of bytes saved on the stack for callee-saved + registers. */ + int callee_saved_reg_size; +}; + +/* Data structures for the eBPF specific built-ins. */ + +/* Maximum number of arguments taken by a builtin function, plus + one. */ +#define BPF_BUILTIN_MAX_ARGS 5 + +enum bpf_builtins +{ + BPF_BUILTIN_UNUSED = 0, + /* Built-ins for kernel helpers. */ +#define DEF_HELPER(V,D,N,T) BPF_BUILTIN_HELPER_##D, +# include "bpf-helpers.def" +#undef DEF_HELPER + BPF_BUILTIN_HELPER_MAX, + /* Built-ins for non-generic loads and stores. */ + BPF_BUILTIN_LOAD_BYTE = BPF_BUILTIN_HELPER_MAX, + BPF_BUILTIN_LOAD_HALF, + BPF_BUILTIN_LOAD_WORD, + BPF_BUILTIN_MAX, +}; + +/* This table is indexed by an enum bpf_builtin. */ +static const char *bpf_helper_names[] = +{ + NULL, +#define DEF_HELPER(V,D,N,T) #N, +# include "bpf-helpers.def" +#undef DEF_HELPER + NULL, + NULL, + NULL, + NULL +}; + +/* Return the builtin code corresponding to the kernel helper builtin + __builtin_NAME, or 0 if the name doesn't correspond to a kernel + helper builtin. */ + +static inline int +bpf_helper_code (const char *name) +{ + int i; + + for (i = 1; i < BPF_BUILTIN_HELPER_MAX; ++i) + if (strcmp (name, bpf_helper_names[i]) == 0) + return i; + + return 0; +} + +static GTY (()) tree bpf_builtins[(int) BPF_BUILTIN_MAX]; + +/* Initialize the per-function machine status. */ + +static struct machine_function * +bpf_init_machine_status (void) +{ + /* Note this initializes all fields to 0, which is just OK for + us. */ + return ggc_cleared_alloc (); +} + +/* Override options and do some other initialization. */ + +static void +bpf_option_override (void) +{ + /* Set the initializer for the per-function status structure. */ + init_machine_status = bpf_init_machine_status; +} + +#undef TARGET_OPTION_OVERRIDE +#define TARGET_OPTION_OVERRIDE bpf_option_override + +/* Define target-specific CPP macros. This function in used in the + definition of TARGET_CPU_CPP_BUILTINS in bpf.h */ + +#define builtin_define(TXT) cpp_define (pfile, TXT) + +void +bpf_target_macros (cpp_reader *pfile) +{ + builtin_define ("__BPF__"); + + if (TARGET_BIG_ENDIAN) + builtin_define ("__BPF_BIG_ENDIAN__"); + else + builtin_define ("__BPF_LITTLE_ENDIAN__"); + + /* Define BPF_KERNEL_VERSION_CODE */ + { + const char *version_code; + char *kernel_version_code; + + switch (bpf_kernel) + { + case LINUX_V4_0: version_code = "0x40000"; break; + case LINUX_V4_1: version_code = "0x40100"; break; + case LINUX_V4_2: version_code = "0x40200"; break; + case LINUX_V4_3: version_code = "0x40300"; break; + case LINUX_V4_4: version_code = "0x40400"; break; + case LINUX_V4_5: version_code = "0x40500"; break; + case LINUX_V4_6: version_code = "0x40600"; break; + case LINUX_V4_7: version_code = "0x40700"; break; + case LINUX_V4_8: version_code = "0x40800"; break; + case LINUX_V4_9: version_code = "0x40900"; break; + case LINUX_V4_10: version_code = "0x40a00"; break; + case LINUX_V4_11: version_code = "0x40b00"; break; + case LINUX_V4_12: version_code = "0x40c00"; break; + case LINUX_V4_13: version_code = "0x40d00"; break; + case LINUX_V4_14: version_code = "0x40e00"; break; + case LINUX_V4_15: version_code = "0x40f00"; break; + case LINUX_V4_16: version_code = "0x41000"; break; + case LINUX_V4_17: version_code = "0x42000"; break; + case LINUX_V4_18: version_code = "0x43000"; break; + case LINUX_V4_19: version_code = "0x44000"; break; + case LINUX_V4_20: version_code = "0x45000"; break; + case LINUX_V5_0: version_code = "0x50000"; break; + case LINUX_V5_1: version_code = "0x50100"; break; + case LINUX_V5_2: version_code = "0x50200"; break; + default: + gcc_unreachable (); + } + + kernel_version_code = ACONCAT (("__BPF_KERNEL_VERSION_CODE__=", + version_code, NULL)); + builtin_define (kernel_version_code); + } +} + +/* Output assembly directives to switch to section NAME. The section + should have attributes as specified by FLAGS, which is a bit mask + of the 'SECTION_*' flags defined in 'output.h'. If DECL is + non-NULL, it is the 'VAR_DECL' or 'FUNCTION_DECL' with which this + section is associated. */ + +static void +bpf_asm_named_section (const char *name, + unsigned int flags ATTRIBUTE_UNUSED, + tree decl ATTRIBUTE_UNUSED) +{ + fprintf (asm_out_file, "\t.section\t%s\n", name); +} + +#undef TARGET_ASM_NAMED_SECTION +#define TARGET_ASM_NAMED_SECTION bpf_asm_named_section + +/* Return an RTX representing the place where a function returns or + receives a value of data type RET_TYPE, a tree node representing a + data type. */ + +static rtx +bpf_function_value (const_tree ret_type, + const_tree fntype_or_decl, + bool outgoing ATTRIBUTE_UNUSED) +{ + enum machine_mode mode; + int unsignedp; + + mode = TYPE_MODE (ret_type); + if (INTEGRAL_TYPE_P (ret_type)) + mode = promote_function_mode (ret_type, mode, &unsignedp, + fntype_or_decl, 1); + + return gen_rtx_REG (mode, BPF_R0); +} + +#undef TARGET_FUNCTION_VALUE +#define TARGET_FUNCTION_VALUE bpf_function_value + +/* Return true if REGNO is the number of a hard register in which the + values of called function may come back. */ + +static bool +bpf_function_value_regno_p (const unsigned int regno) +{ + return (regno == BPF_R0); +} + +#undef TARGET_FUNCTION_VALUE_REGNO_P +#define TARGET_FUNCTION_VALUE_REGNO_P bpf_function_value_regno_p + +/* Compute the size of the function's stack frame, including the local + area and the register-save area. */ + +static void +bpf_compute_frame_layout (void) +{ + int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT; + int padding_locals, regno; + + /* Set the space used in the stack by local variables. This is + rounded up to respect the minimum stack alignment. */ + cfun->machine->local_vars_size = get_frame_size (); + + padding_locals = cfun->machine->local_vars_size % stack_alignment; + if (padding_locals) + padding_locals = stack_alignment - padding_locals; + + cfun->machine->local_vars_size += padding_locals; + + /* Set the space used in the stack by callee-saved used registers in + the current function. There is no need to round up, since the + registers are all 8 bytes wide. */ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if ((!fixed_regs[regno] + && df_regs_ever_live_p (regno) + && !call_used_regs[regno]) + || (cfun->calls_alloca + && regno == STACK_POINTER_REGNUM)) + cfun->machine->callee_saved_reg_size += 8; + + /* Check that the total size of the frame doesn't exceed the limit + imposed by eBPF. */ + if ((cfun->machine->local_vars_size + + cfun->machine->callee_saved_reg_size) > bpf_frame_limit) + { + static int stack_limit_exceeded = 0; + + if (!stack_limit_exceeded) + error ("eBPF stack limit exceeded"); + stack_limit_exceeded = 1; + } +} + +#undef TARGET_COMPUTE_FRAME_LAYOUT +#define TARGET_COMPUTE_FRAME_LAYOUT bpf_compute_frame_layout + +/* Expand to the instructions in a function prologue. This function + is called when expanding the 'prologue' pattern in bpf.md. */ + +void +bpf_expand_prologue (void) +{ + int regno, fp_offset; + rtx insn; + HOST_WIDE_INT size; + + size = (cfun->machine->local_vars_size + + cfun->machine->callee_saved_reg_size); + fp_offset = -cfun->machine->local_vars_size; + + /* Save callee-saved hard registes. The register-save-area starts + right after the local variables. */ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + { + if ((!fixed_regs[regno] + && df_regs_ever_live_p (regno) + && !call_used_regs[regno]) + || (cfun->calls_alloca + && regno == STACK_POINTER_REGNUM)) + { + rtx mem; + + if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff)) + /* This has been already reported as an error in + bpf_compute_frame_layout. */ + break; + else + { + mem = gen_frame_mem (DImode, + plus_constant (DImode, + hard_frame_pointer_rtx, + fp_offset - 8)); + insn = emit_move_insn (mem, gen_rtx_REG (DImode, regno)); + RTX_FRAME_RELATED_P (insn) = 1; + fp_offset -= 8; + } + } + } + + /* Set the stack pointer, if the function allocates space + dynamically. Note that the value of %sp should be directly + derived from %fp, for the kernel verifier to track it as a stack + accessor. */ + if (cfun->calls_alloca) + { + insn = emit_move_insn (stack_pointer_rtx, + hard_frame_pointer_rtx); + RTX_FRAME_RELATED_P (insn) = 1; + + if (size > 0) + { + insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (-size)))); + RTX_FRAME_RELATED_P (insn) = 1; + } + } +} + +/* Expand to the instructions in a function epilogue. This function + is called when expanding the 'epilogue' pattern in bpf.md. */ + +void +bpf_expand_epilogue (void) +{ + int regno, fp_offset; + rtx insn; + + fp_offset = -cfun->machine->local_vars_size; + + /* Restore callee-saved hard registes from the stack. */ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + { + if ((!fixed_regs[regno] + && df_regs_ever_live_p (regno) + && !call_used_regs[regno]) + || (cfun->calls_alloca + && regno == STACK_POINTER_REGNUM)) + { + rtx mem; + + if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff)) + /* This has been already reported as an error in + bpf_compute_frame_layout. */ + break; + else + { + mem = gen_frame_mem (DImode, + plus_constant (DImode, + hard_frame_pointer_rtx, + fp_offset - 8)); + insn = emit_move_insn (gen_rtx_REG (DImode, regno), mem); + RTX_FRAME_RELATED_P (insn) = 1; + fp_offset -= 8; + } + } + } + + emit_jump_insn (gen_exit ()); +} + +/* Return the initial difference between the specified pair of + registers. The registers that can figure in FROM, and TO, are + specified by ELIMINABLE_REGS in bpf.h. + + This function is used in the definition of + INITIAL_ELIMINATION_OFFSET in bpf.h */ + +HOST_WIDE_INT +bpf_initial_elimination_offset (int from, int to) +{ + HOST_WIDE_INT ret; + + if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) + ret = (cfun->machine->local_vars_size + + cfun->machine->callee_saved_reg_size); + else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) + ret = 0; + else + gcc_unreachable (); + + return ret; +} + +/* Return the number of consecutive hard registers, starting at + register number REGNO, required to hold a value of mode MODE. */ + +static unsigned int +bpf_hard_regno_nregs (unsigned int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS bpf_hard_regno_nregs + +/* Return true if it is permissible to store a value of mode MODE in + hard register number REGNO, or in several registers starting with + that one. */ + +static bool +bpf_hard_regno_mode_ok (unsigned int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + switch (mode) + { + case E_SImode: + case E_DImode: + case E_HImode: + case E_QImode: + case E_TImode: + case E_SFmode: + case E_DFmode: + return true; + default: + return false; + } +} + +#undef TARGET_HARD_REGNO_MODE_OK +#define TARGET_HARD_REGNO_MODE_OK bpf_hard_regno_mode_ok + +/* Return true if a function must have and use a frame pointer. */ + +static bool +bpf_frame_pointer_required (void) +{ + /* We do not have a stack pointer, so we absolutely depend on the + frame-pointer in order to access the stack... and fishes walk and + pigs fly glglgl */ + return true; +} + +#undef TARGET_FRAME_POINTER_REQUIRED +#define TARGET_FRAME_POINTER_REQUIRED bpf_frame_pointer_required + +/* Return `true' if the given RTX X is a valid base for an indirect + memory access. STRICT has the same meaning than in + bpf_legitimate_address_p. */ + +static inline bool +bpf_address_base_p (rtx x, bool strict) +{ + return (GET_CODE (x) == REG + && (REGNO (x) < 11 + || (!strict && REGNO (x) >= FIRST_PSEUDO_REGISTER))); +} + +/* Return true if X (a RTX) is a legitimate memory address on the + target machine for a memory operand of mode MODE. */ + +static bool +bpf_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, + rtx x, + bool strict) +{ + switch (GET_CODE (x)) + { + case REG: + return bpf_address_base_p (x, strict); + + case PLUS: + { + /* Accept (PLUS ADDR_BASE CONST_INT), provided CONST_INT fits + in a signed 16-bit. + + Note that LABEL_REF and SYMBOL_REF are not allowed in + REG+IMM addresses, because it is almost certain they will + overload the offset field. */ + + rtx x0 = XEXP (x, 0); + rtx x1 = XEXP (x, 1); + + if (bpf_address_base_p (x0, strict) && GET_CODE (x1) == CONST_INT) + return IN_RANGE (INTVAL (x1), -1 - 0x7fff, 0x7fff); + + break; + } + default: + break; + } + + return false; +} + +#undef TARGET_LEGITIMATE_ADDRESS_P +#define TARGET_LEGITIMATE_ADDRESS_P bpf_legitimate_address_p + +/* Describe the relative costs of RTL expressions. Return true when + all subexpressions of X have been processed, and false when + `rtx_cost' should recurse. */ + +static bool +bpf_rtx_costs (rtx x ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + int outer_code ATTRIBUTE_UNUSED, + int opno ATTRIBUTE_UNUSED, + int *total ATTRIBUTE_UNUSED, + bool speed ATTRIBUTE_UNUSED) +{ + /* To be written. */ + return false; +} + +#undef TARGET_RTX_COSTS +#define TARGET_RTX_COSTS bpf_rtx_costs + +/* Return true if an argument at the position indicated by CUM should + be passed by reference. If the hook returns true, a copy of that + argument is made in memory and a pointer to the argument is passed + instead of the argument itself. */ + +static bool +bpf_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, + const function_arg_info &arg) +{ + unsigned num_bytes = arg.type_size_in_bytes (); + + /* Pass aggregates and values bigger than 5 words by reference. + Everything else is passed by copy. */ + return (arg.aggregate_type_p () || (num_bytes > 8*5)); +} + +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE bpf_pass_by_reference + +/* Return a RTX indicating whether a function argument is passed in a + register and if so, which register. */ + +static rtx +bpf_function_arg (cumulative_args_t ca, const function_arg_info &arg) +{ + CUMULATIVE_ARGS *cum = get_cumulative_args (ca); + + if (*cum < 5) + return gen_rtx_REG (arg.mode, *cum + 1); + else + /* An error will be emitted for this in + bpf_function_arg_advance. */ + return NULL_RTX; +} + +#undef TARGET_FUNCTION_ARG +#define TARGET_FUNCTION_ARG bpf_function_arg + +/* Update the summarizer variable pointed by CA to advance past an + argument in the argument list. */ + +static void +bpf_function_arg_advance (cumulative_args_t ca, + const function_arg_info &arg) +{ + CUMULATIVE_ARGS *cum = get_cumulative_args (ca); + unsigned num_bytes = arg.type_size_in_bytes (); + unsigned num_words = CEIL (num_bytes, UNITS_PER_WORD); + + if (*cum <= 5 && *cum + num_words > 5) + error ("too many function arguments for eBPF"); + + *cum += num_words; +} + +#undef TARGET_FUNCTION_ARG_ADVANCE +#define TARGET_FUNCTION_ARG_ADVANCE bpf_function_arg_advance + +/* Output the assembly code for a constructor. Since eBPF doesn't + support indirect calls, constructors are not supported. */ + +static void +bpf_output_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED) +{ + tree decl = SYMBOL_REF_DECL (symbol); + + if (decl) + sorry_at (DECL_SOURCE_LOCATION (decl), + "no constructors"); + else + sorry ("no constructors"); +} + +#undef TARGET_ASM_CONSTRUCTOR +#define TARGET_ASM_CONSTRUCTOR bpf_output_constructor + +/* Output the assembly code for a destructor. Since eBPF doesn't + support indirect calls, destructors are not supported. */ + +static void +bpf_output_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED) +{ + tree decl = SYMBOL_REF_DECL (symbol); + + if (decl) + sorry_at (DECL_SOURCE_LOCATION (decl), + "no destructors"); + else + sorry ("no destructors"); +} + +#undef TARGET_ASM_DESTRUCTOR +#define TARGET_ASM_DESTRUCTOR bpf_output_destructor + +/* Return the appropriate instruction to CALL to a function. TARGET + is an RTX denoting the address of the called function. + + The main purposes of this function are: + - To reject indirect CALL instructions, which are not supported by + eBPF. + - To recognize calls to kernel helper functions and emit the + corresponding CALL N instruction. + + This function is called from the expansion of the 'call' pattern in + bpf.md. */ + +const char * +bpf_output_call (rtx target) +{ + rtx xops[1]; + + switch (GET_CODE (target)) + { + case CONST_INT: + output_asm_insn ("call\t%0", &target); + break; + case SYMBOL_REF: + { + const char *function_name = XSTR (target, 0); + int code; + + if (strncmp (function_name, "__builtin_bpf_helper_", 21) == 0 + && ((code = bpf_helper_code (function_name + 21)) != 0)) + { + xops[0] = GEN_INT (code); + output_asm_insn ("call\t%0", xops); + } + else + output_asm_insn ("call\t%0", &target); + + break; + } + default: + error ("indirect call in function, which are not supported by eBPF"); + output_asm_insn ("call 0", NULL); + break; + } + + return ""; +} + +/* Print an instruction operand. This function is called in the macro + PRINT_OPERAND defined in bpf.h */ + +void +bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED) +{ + switch (GET_CODE (op)) + { + case REG: + fprintf (file, "%s", reg_names[REGNO (op)]); + break; + case MEM: + output_address (GET_MODE (op), XEXP (op, 0)); + break; + case CONST_DOUBLE: + if (CONST_DOUBLE_HIGH (op)) + fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, + CONST_DOUBLE_HIGH (op), CONST_DOUBLE_LOW (op)); + else if (CONST_DOUBLE_LOW (op) < 0) + fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (op)); + else + fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (op)); + break; + default: + output_addr_const (file, op); + } +} + +/* Print an operand which is an address. This function should handle + any legit address, as accepted by bpf_legitimate_address_p, and + also addresses that are valid in CALL instructions. + + This function is called in the PRINT_OPERAND_ADDRESS macro defined + in bpf.h */ + +void +bpf_print_operand_address (FILE *file, rtx addr) +{ + switch (GET_CODE (addr)) + { + case REG: + fprintf (file, "[%s+0]", reg_names[REGNO (addr)]); + break; + case PLUS: + { + rtx op0 = XEXP (addr, 0); + rtx op1 = XEXP (addr, 1); + + if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT) + { + fprintf (file, "[%s+", reg_names[REGNO (op0)]); + output_addr_const (file, op1); + fputs ("]", file); + } + else + fatal_insn ("invalid address in operand", addr); + break; + } + case MEM: + /* Fallthrough. */ + case LABEL_REF: + /* Fallthrough. */ + fatal_insn ("unsupported operand", addr); + break; + default: + output_addr_const (file, addr); + break; + } +} + +/* Add a BPF builtin function with NAME, CODE and TYPE. Return + the function decl or NULL_TREE if the builtin was not added. */ + +static tree +def_builtin (const char *name, enum bpf_builtins code, tree type) +{ + tree t + = add_builtin_function (name, type, code, BUILT_IN_MD, NULL, NULL_TREE); + + bpf_builtins[code] = t; + return t; +} + +/* Define machine-specific built-in functions. */ + +static void +bpf_init_builtins (void) +{ + /* Built-ins for calling kernel helpers. */ + + tree pt = build_pointer_type (void_type_node); + tree const_void_type + = build_qualified_type (void_type_node, TYPE_QUAL_CONST); + tree cpt = build_pointer_type (const_void_type); + tree st = short_integer_type_node; + tree ust = uint16_type_node; + tree it = integer_type_node; + tree ut = unsigned_type_node; + tree const_char_type + = build_qualified_type (char_type_node, TYPE_QUAL_CONST); + tree cst = build_pointer_type (const_char_type); + tree vt = void_type_node; + tree ult = long_unsigned_type_node; + tree u32t = uint32_type_node; + tree u64t = uint64_type_node; + tree llt = long_long_integer_type_node; + tree ullt = long_long_unsigned_type_node; + +#define TYPES build_function_type_list +#define VTYPES build_varargs_function_type_list +#define DEF_HELPER(V,D,N,T) \ + do \ + { \ + if (bpf_kernel >= (V)) \ + def_builtin ("__builtin_bpf_helper_" #N, \ + BPF_BUILTIN_HELPER_##D, \ + T); \ + } while (0); +# include "bpf-helpers.def" +#undef TYPES +#undef VTYPES +#undef DEF_HELPER + + /* Built-ins for BPF_LD_ABS and BPF_LD_IND instructions. */ + + def_builtin ("__builtin_bpf_load_byte", BPF_BUILTIN_LOAD_BYTE, + build_function_type_list (ullt, ullt, 0)); + def_builtin ("__builtin_bpf_load_half", BPF_BUILTIN_LOAD_HALF, + build_function_type_list (ullt, ullt, 0)); + def_builtin ("__builtin_bpf_load_word", BPF_BUILTIN_LOAD_WORD, + build_function_type_list (ullt, ullt, 0)); +} + +#undef TARGET_INIT_BUILTINS +#define TARGET_INIT_BUILTINS bpf_init_builtins + +/* Expand a call to a BPF-specific built-in function that was set up + with bpf_init_builtins. */ + +static rtx +bpf_expand_builtin (tree exp, rtx target, + rtx subtarget ATTRIBUTE_UNUSED, + machine_mode mode ATTRIBUTE_UNUSED, + int ignore) +{ + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); + int code = DECL_MD_FUNCTION_CODE (fndecl); + + if (code >= 1 && code < BPF_BUILTIN_HELPER_MAX) + { + /* This is a builtin to call a kernel helper function. + + For these builtins, we just expand the function call normally + with expand_call like we would do for a libcall. The function + bpf_output_call below will then do The Right Thing (TM), + recognizing the name of the called __builtin_helper_* symbol + and emitting the corresponding CALL N instruction whenever + necessary. */ + + return expand_call (exp, target, ignore); + } + else if (code == BPF_BUILTIN_LOAD_BYTE + || code == BPF_BUILTIN_LOAD_HALF + || code == BPF_BUILTIN_LOAD_WORD) + { + /* Expand an indirect load from the sk_buff in the context. + There is just one argument to the builtin, which is the + offset. + + We try first to expand a ldabs* instruction. In case this + fails, we try a ldind* instruction. */ + + enum insn_code abs_icode + = (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldabsb + : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldabsh + : CODE_FOR_ldabsw); + + enum insn_code ind_icode + = (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldindb + : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldindh + : CODE_FOR_ldindw); + + tree offset_arg = CALL_EXPR_ARG (exp, 0); + struct expand_operand ops[2]; + + create_input_operand (&ops[0], expand_normal (offset_arg), + TYPE_MODE (TREE_TYPE (offset_arg))); + create_input_operand (&ops[1], const0_rtx, SImode); + + if (!maybe_expand_insn (abs_icode, 2, ops) + && !maybe_expand_insn (ind_icode, 2, ops)) + { + error ("invalid argument to built-in function"); + return gen_rtx_REG (ops[0].mode, BPF_R0); + } + + /* The result of the load is in R0. */ + return gen_rtx_REG (ops[0].mode, BPF_R0); + } + + gcc_unreachable (); +} + +#undef TARGET_EXPAND_BUILTIN +#define TARGET_EXPAND_BUILTIN bpf_expand_builtin + +/* Initialize target-specific function library calls. This is mainly + used to call library-provided soft-fp operations, since eBPF + doesn't support floating-point in "hardware". */ + +static void +bpf_init_libfuncs (void) +{ + set_conv_libfunc (sext_optab, DFmode, SFmode, + "__bpf_extendsfdf2"); + set_conv_libfunc (trunc_optab, SFmode, DFmode, + "__bpf_truncdfsf2"); + set_conv_libfunc (sfix_optab, SImode, DFmode, + "__bpf_fix_truncdfsi"); + set_conv_libfunc (sfloat_optab, DFmode, SImode, + "__bpf_floatsidf"); + set_conv_libfunc (ufloat_optab, DFmode, SImode, + "__bpf_floatunsidf"); +} + +#undef TARGET_INIT_LIBFUNCS +#define TARGET_INIT_LIBFUNCS bpf_init_libfuncs + +/* Define the mechanism that will be used for describing frame unwind + information to the debugger. In eBPF it is not possible to unwind + frames. */ + +static enum unwind_info_type +bpf_debug_unwind_info () +{ + return UI_NONE; +} + +#undef TARGET_DEBUG_UNWIND_INFO +#define TARGET_DEBUG_UNWIND_INFO bpf_debug_unwind_info + +/* Output assembly directives to assemble data of various sized and + alignments. */ + +#undef TARGET_ASM_BYTE_OP +#define TARGET_ASM_BYTE_OP "\t.byte\t" +#undef TARGET_ASM_ALIGNED_HI_OP +#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" +#undef TARGET_ASM_ALIGNED_SI_OP +#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" +#undef TARGET_ASM_ALIGNED_DI_OP +#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t" + +/* Finally, build the GCC target. */ + +struct gcc_target targetm = TARGET_INITIALIZER; + +#include "gt-bpf.h" diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h new file mode 100644 index 00000000000..70ad818ccf8 --- /dev/null +++ b/gcc/config/bpf/bpf.h @@ -0,0 +1,539 @@ +/* Definition of the eBPF target for GCC. + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#ifndef GCC_BPF_H +#define GCC_BPF_H + +/**** Controlling the Compilation Driver. */ + +#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}" +#define LINK_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}" +#define LIB_SPEC "" +#define STARTFILE_SPEC "" + +/**** Run-time Target Specification. */ + +#define TARGET_CPU_CPP_BUILTINS() bpf_target_macros (pfile) + +/**** Storage Layout. */ + +/* Endianness and word size. */ +#define BITS_BIG_ENDIAN 0 +#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN) +#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN) +#define BITS_PER_WORD 64 +#define UNITS_PER_WORD 8 + +/* When storing an integer whose size is less than 64-bit in a + register, promote it to a DImode. */ +#define PROMOTE_MODE(M, UNSIGNEDP, TYPE) \ + do \ + { \ + if (GET_MODE_CLASS (M) == MODE_INT \ + && GET_MODE_SIZE (M) < 8) \ + M = DImode; \ + } while (0) + +/* Biggest alignment supported by the object file format of this + machine. In this case this is ELF. Use the same definition than + in elfos.h */ +#define MAX_OFILE_ALIGNMENT (((unsigned int) 1 << 28) * 8) + +/* Align argument parameters on the stack to 64-bit, at a minimum. */ +#define PARM_BOUNDARY 64 + +/* The hardware enforces that the stack pointer should be aligned to + 64-bit at any time. */ +#define STACK_BOUNDARY 64 + +/* Function entry points are aligned to 128 bits. */ +#define FUNCTION_BOUNDARY 128 + +/* Maximum alignment required by data of any type. */ +#define BIGGEST_ALIGNMENT 64 + +/* The best alignment to use in cases where we have a choice. */ +#define FASTEST_ALIGNMENT 64 + +/* Use a fast alignment when storing arrays of chars in a local. */ +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ + (TREE_CODE (TYPE) == ARRAY_TYPE \ + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ + && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN)) + +/* The load and store instructions won't work if the data is not in + it's expected alignment. */ +#define STRICT_ALIGNMENT 1 + +/* We use Pmode as the mode of the size increment operand in an + `allocate_stack' pattern. */ +#define STACK_SIZE_MODE Pmode + +/**** Layout of Source Language Data Types. */ + +#define INT_TYPE_SIZE 32 +#define SHORT_TYPE_SIZE 16 +#define LONG_TYPE_SIZE 64 +#define LONG_LONG_TYPE_SIZE 64 +#define CHAR_TYPE_SIZE 8 +#define FLOAT_TYPE_SIZE 32 +#define DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE 64 + +#define INTPTR_TYPE "long int" +#define UINTPTR_TYPE "long unsigned int" +#define SIZE_TYPE "long unsigned int" +#define PTRDIFF_TYPE "long int" + +#define SIG_ATOMIC_TYPE "char" + +#define INT8_TYPE "char" +#define INT16_TYPE "short int" +#define INT32_TYPE "int" +#define INT64_TYPE "long int" +#define UINT8_TYPE "unsigned char" +#define UINT16_TYPE "short unsigned int" +#define UINT32_TYPE "unsigned int" +#define UINT64_TYPE "long unsigned int" + +#define INT_LEAST8_TYPE INT8_TYPE +#define INT_LEAST16_TYPE INT16_TYPE +#define INT_LEAST32_TYPE INT32_TYPE +#define INT_LEAST64_TYPE INT64_TYPE +#define UINT_LEAST8_TYPE UINT8_TYPE +#define UINT_LEAST16_TYPE UINT16_TYPE +#define UINT_LEAST32_TYPE UINT32_TYPE +#define UINT_LEAST64_TYPE UINT64_TYPE + +#define INT_FAST8_TYPE INT8_TYPE +#define INT_FAST16_TYPE INT16_TYPE +#define INT_FAST32_TYPE INT32_TYPE +#define INT_FAST64_TYPE INT64_TYPE +#define UINT_FAST8_TYPE UINT8_TYPE +#define UINT_FAST16_TYPE UINT16_TYPE +#define UINT_FAST32_TYPE UINT32_TYPE +#define UINT_FAST64_TYPE UINT64_TYPE + +/* `char' is signed by default, like in x86. */ +#define DEFAULT_SIGNED_CHAR 1 + +/* `wchar_t' is a signed 32-bit type. The second constant is used by + cpp, which can't use WCHAR_TYPE. */ +#define WCHAR_TYPE "int" +#define WCHAR_TYPE_SIZE 32 + +/* `wint_t' is a signed 32-bit type. */ +#define WINT_TYPE "int" +#define WINT_TYPE_SIZE 32 + +/**** Register Usage. */ + +/*** Basic Characteristics of Registers. */ + +#define BPF_R0 0 +#define BPF_R1 1 +#define BPF_R2 2 +#define BPF_R3 3 +#define BPF_R4 4 +#define BPF_R5 5 +#define BPF_R6 6 +#define BPF_CTX BPF_R6 +#define BPF_R7 7 +#define BPF_R8 8 +#define BPF_R9 9 +#define BPF_SP BPF_R9 +#define BPF_R10 10 +#define BPF_FP BPF_R10 +/* 11 is not a real eBPF hard register and is eliminated or not used + in the final assembler. See below. */ + +#define FIRST_PSEUDO_REGISTER 12 + +/* The registers %r0..%r8 are available for general allocation. + %r9 is the pseudo-stack pointer. + %r10 is the stack frame, which is read-only. + %r11 (__arg__) is a fake register that always gets eliminated. */ +#define FIXED_REGISTERS \ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1} + +/* %r0..%r5 are clobbered by function calls. */ +#define CALL_USED_REGISTERS \ + {1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1} + +/**** Register Classes. */ + +enum reg_class +{ + NO_REGS, /* no registers in set. */ + ALL_REGS, /* all registers. */ + LIM_REG_CLASSES /* max value + 1. */ +}; + +#define N_REG_CLASSES (int) LIM_REG_CLASSES +#define GENERAL_REGS ALL_REGS + +/* An initializer containing the names of the register classes as C + string constants. These names are used in writing some of the + debugging dumps. */ +#define REG_CLASS_NAMES \ +{ \ + "NO_REGS", \ + "ALL_REGS" \ +} + +/* An initializer containing the contents of the register classes, as + integers which are bit masks. The Nth integer specifies the + contents of class N. The way the integer MASK is interpreted is + that register R is in the class if `MASK & (1 << R)' is 1. + + In eBPF all the hard registers are considered general-purpose + integer registers. */ +#define REG_CLASS_CONTENTS \ +{ \ + 0x00000000, /* NO_REGS */ \ + 0x00000fff, /* ALL_REGS */ \ +} + +/* A C expression whose value is a register class containing hard + register REGNO. In general there is more that one such class; + choose a class which is "minimal", meaning that no smaller class + also contains the register. */ +#define REGNO_REG_CLASS(REGNO) GENERAL_REGS + +/* A macro whose definition is the name of the class to which a + valid base register must belong. A base register is one used in + an address which is the register value plus a displacement. */ +#define BASE_REG_CLASS GENERAL_REGS + +/* A macro whose definition is the name of the class to which a + valid index register must belong. An index register is one used + in an address where its value is either multiplied by a scale + factor or added to another register (as well as added to a + displacement). */ +#define INDEX_REG_CLASS NO_REGS + +/* C expression which is nonzero if register number REGNO is suitable + for use as a base register in operand addresses. In eBPF every + hard register can be used for this purpose. */ +#define REGNO_OK_FOR_BASE_P(REGNO) \ + ((REGNO) < FIRST_PSEUDO_REGISTER) + +/* C expression which is nonzero if register number REGNO is suitable + for use as an index register in operand addresses. */ +#define REGNO_OK_FOR_INDEX_P(REGNO) false + +/**** Debugging Info ****/ + +/* We cannot support DWARF2 because of the limitations of eBPF. */ +#define DBX_DEBUGGING_INFO + +/**** Stack Layout and Calling Conventions. */ + +/*** Basic Stack Layout. */ + +#define STACK_GROWS_DOWNWARD 1 +#define FRAME_GROWS_DOWNWARD 1 + +/* The argument pointer always points to the first argument. */ +#define FIRST_PARM_OFFSET(FNDECL) 0 + +/* Unsupported. */ +#define RETURN_ADDR_RTX(count, frame) const0_rtx + +/*** Registers That Address the Stack Frame. */ + +#define FRAME_POINTER_REGNUM 10 +#define STACK_POINTER_REGNUM 9 +#define ARG_POINTER_REGNUM 11 +#define STATIC_CHAIN_REGNUM 8 + +/*** Registers elimination. */ + +#define ELIMINABLE_REGS \ + {{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ + { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }} + +/* Define the offset between two registers, one to be eliminated, and + the other its replacement, at the start of a routine. */ +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ + do \ + { \ + (OFFSET) = bpf_initial_elimination_offset ((FROM), (TO)); \ + } while (0) + +/*** Passing Function Arguments on the Stack. */ + +/* The eBPF ABI doesn't support passing arguments on the stack. Only + in the first five registers. Code in bpf.c assures the stack is + never used when passing arguments. However, we still have to + define the constants below. */ + +/* If nonzero, push insns will be used to pass outgoing arguments. */ +#define PUSH_ARGS 0 + +/* If nonzero, function arguments will be evaluated from last to + first, rather than from first to last. */ +#define PUSH_ARGS_REVERSED 1 + +/* Allocate stack space for arguments at the beginning of each + function. */ +#define ACCUMULATE_OUTGOING_ARGS 1 + +/*** Passing Arguments in Registers. */ + +/* Use an integer in order to keep track of the number of arguments + passed to a function in integer registers, up to + MAX_ARGS_IN_REGISTERS. */ +#define CUMULATIVE_ARGS int + +/* INIT_CUMULATIVE_ARGS initializes a variable CUM of type + CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ +#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \ + memset (&(CUM), 0, sizeof (CUM)) + +/* Nonzero if N is the number of a hard register in which function + arguments are sometimes passed. */ +#define FUNCTION_ARG_REGNO_P(N) ((N) >= 1 && (N) <= 5) + +/*** How Scalar Function Values are Returned. */ + +/* Define how to find the value returned by a library function + assuming the value has mode MODE. This is always %r0 for eBPF. */ +#define LIBCALL_VALUE(MODE) \ + gen_rtx_REG ((MODE), 0) + +/*** Generating Code for Profiling. */ + +/* We do not support profiling yet, so do not call `mcount'. */ +#define FUNCTION_PROFILER(FILE, LABELNO) do { } while (0) + +/*** Function Entry and Exit. */ + +/* We do not require an accurate stack pointer at function return. + This is because the stack pointer's original value is initialized + from the frame pointer, rather than decreased, to satisfy the + kernel's verifier. Thus, we have to save the stack pointer in + function prologue and restore it in function epilogue. If + EXIT_IGNORE_STACK is not set, then superfluous instructions are + generated to save and restore the stack pointer after and before + the function epilogue, respectively. */ +#define EXIT_IGNORE_STACK 1 + +/**** Support for Nested Functions. */ + +/* We have to define TRAMPOLINE_SIZE even if we don't ever generate + them. Set to 64 arbitrarily. */ +#define TRAMPOLINE_SIZE 64 + +/**** Addressing Modes. */ + +/* Maximum number of registers that can appear in a valid memory + address. */ +#define MAX_REGS_PER_ADDRESS 1 + +/* 1 if X is an rtx for a constant that is a valid address. */ + +#define CONSTANT_ADDRESS_P(X) 0 + +/**** Describing Relative Costs of Operations. */ + +/* Cost of a branch instruction. A value of 1 is the default. */ +#define BRANCH_COST(SPEED_P,PREDICTABLE_P) 1 + +/* The SPARC port says: Nonzero if access to memory by bytes is slow + and undesirable. For RISC chips, it means that access to memory by + bytes is no better than access by words when possible, so grab a + whole word and maybe make use of that. */ +#define SLOW_BYTE_ACCESS 1 + +/* Threshold of number of scalar memory-to-memory move instructions, + _below_ which a sequence of insns should be generated instead of a + string move insn or a library call. */ +#define MOVE_RATIO(speed) 128 + +/* Threshold of number of scalar move instructions, _below_ which a + sequence of insns should be generated to clear memory instead of a + string clear insn or a library call. */ +#define CLEAR_RATIO(speed) 128 + +/* Threshold of number of scalar move instructions, _below_ which a + sequence of insns should be generated to set memory to a constant + value, instead of a block set insn or a library call. */ +#define SET_RATIO(speed) 128 + +/* True if it is as good or better to call a constant function address + than to call an address kept in a register. */ +#define NO_FUNCTION_CSE 1 + +/**** Dividing the Output into Sections. */ + +#define TEXT_SECTION_ASM_OP "\t.text" +#define DATA_SECTION_ASM_OP "\t.data" +#define BSS_SECTION_ASM_OP "\t.bss" +#define COMMON_ASM_OP "\t.common\t" + +/**** Defining the Output Assembler Language. */ + +/*** The Overall Framework of an Assembler File. */ + +#define ASM_COMMENT_START ";" + +/* Output to assembler file text saying following lines + may contain character constants, extra white space, comments, etc. */ + +#ifndef ASM_APP_ON +#define ASM_APP_ON " #APP\n" +#endif + +/* Output to assembler file text saying following lines + no longer contain unusual constructs. */ + +#ifndef ASM_APP_OFF +#define ASM_APP_OFF " #NO_APP\n" +#endif + +/*** Output of Data. */ + +/*** Output of Uninitialized Variables. */ + +/* How to output an assembler line to define a local common + symbol. */ + +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ + do \ + { \ + fprintf ((FILE), "%s", COMMON_ASM_OP); \ + assemble_name ((FILE), (NAME)); \ + fprintf ((FILE), ",%u,%u\n", (int)(SIZE), (ALIGN) / (BITS_PER_UNIT)); \ + } \ + while (0) + +/* A C statement (sans semicolon) to output to the stdio stream + FILE the assembler definition of uninitialized global DECL named + NAME whose size is SIZE bytes and alignment is ALIGN bytes. + Try to use asm_output_aligned_bss to implement this macro. */ + +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ + do { \ + ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \ + } while (0) + +/* This says how to output an assembler line to define a local common + symbol. */ + +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE,NAME,SIZE,ALIGN) \ + ( fputs ("\t.lcomm ", (FILE)), \ + assemble_name ((FILE), (NAME)), \ + fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED "\n", \ + (SIZE), ((ALIGN) / BITS_PER_UNIT))) + +/*** Output and Generation of Labels. */ + +/* Globalizing directive for a label. */ +#define GLOBAL_ASM_OP "\t.global\t" + +/* This is how to store into the string LABEL + the symbol_ref name of an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. + This is suitable for output with `assemble_name'. */ + +#undef ASM_GENERATE_INTERNAL_LABEL +#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ + sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM)) + +/*** Macros Controlling Initialization Routines. */ + +#define INIT_SECTION_ASM_OP "\t.init" +#define FINI_SECTION_ASM_OP "\t.fini" + +/*** Output of Assembler Instructions. */ + +#define REGISTER_NAMES \ + { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \ + "%r8", "%r9", "%fp", "__arg__" } + +#define ADDITIONAL_REGISTER_NAMES \ + { { "%a", 0 }, { "%ctx", 6 }, { "%r10" , 10 } } + +#define LOCAL_LABEL_PREFIX "." +#define USER_LABEL_PREFIX "" + +#define PRINT_OPERAND(STREAM,X,CODE) \ + bpf_print_operand ((STREAM),(X),(CODE)) + +#define PRINT_OPERAND_ADDRESS(STREAM,X) \ + bpf_print_operand_address ((STREAM), (X)) + +/*** Assembler Commands for Alignment. */ + +/* This is how to output an assembler line that says to advance the + location counter to a multiple of 2**LOG bytes. */ +#define ASM_OUTPUT_ALIGN(STREAM,LOG) \ + fprintf (STREAM, "\t.align\t%d\n", (LOG)) + +/* This is how to output an assembler line + that says to advance the location counter by SIZE bytes. */ +#define ASM_OUTPUT_SKIP(FILE,SIZE) \ + fprintf (FILE, "\t.skip\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n", (SIZE)) + +/**** Miscellaneous Parameters. */ + +/* Specify the machine mode that this machine uses for the index in + the tablejump instruction. */ +#define CASE_VECTOR_MODE DImode + +/* Define if operations between registers with integral mode smaller + than a word are always performed on the entire register. */ +#define WORD_REGISTER_OPERATIONS 1 + +/* C expression indicating when insns that read memory in MEM_MODE, an + integral mode narrower than a word, set the bits outsize of + MEM_MODE to be either the sign-extension or the zero-extension of + the data read. */ +#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND + +/* The maximum number of bytes that a single instruction can move + quickly between memory and registers or between two memory + locations. */ +#define MOVE_MAX 8 + +/* An alias for the machine mode for pointers. */ +#define Pmode DImode + +/* An alias for the machine mode used for memory references to + functions being called, in 'call' RTL expressions. */ +#define FUNCTION_MODE Pmode + +/* No libm on eBPF (for now.) */ +#define MATH_LIBRARY "" + +/**** libgcc settings. */ + +/* Iterating over the global constructors and destructors and + executing them requires the ability of doing indirect calls. + + eBPF doesn't support indirect calls, so no chance of supporting + constructors and destructors. */ +#define DO_GLOBAL_CTORS_BODY \ + do { } while (0) +#define DO_GLOBAL_DTORS_BODY \ + do { } while (0) + +#endif /* ! GCC_BPF_H */ diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md new file mode 100644 index 00000000000..4c79522babf --- /dev/null +++ b/gcc/config/bpf/bpf.md @@ -0,0 +1,497 @@ +;; Machine description for eBPF. +;; Copyright (C) 2019 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(include "predicates.md") +(include "constraints.md") + +;;;; Unspecs + +(define_c_enum "unspec" [ + UNSPEC_LDINDABS + UNSPEC_XADD +]) + +;;;; Constants + +(define_constants + [(R0_REGNUM 0) + (R1_REGNUM 1) + (R2_REGNUM 2) + (R3_REGNUM 3) + (R4_REGNUM 4) + (R5_REGNUM 5) + (R6_REGNUM 6) + (R7_REGNUM 7) + (R8_REGNUM 8) + (R9_REGNUM 9) + (R10_REGNUM 10) + (R11_REGNUM 11) +]) + +;;;; Attributes + +;; Instruction classes. +;; alu 64-bit arithmetic. +;; alu32 32-bit arithmetic. +;; end endianness conversion instructions. +;; ld load instructions. +;; lddx load 64-bit immediate instruction. +;; ldx generic load instructions. +;; st generic store instructions for immediates. +;; stx generic store instructions. +;; jmp jump instructions. +;; xadd atomic exchange-and-add instructions. +;; multi multiword sequence (or user asm statements). + +(define_attr "type" + "unknown,alu,alu32,end,ld,lddw,ldx,st,stx,jmp,xadd,multi" + (const_string "unknown")) + +;; Length of instruction in bytes. +(define_attr "length" "" + (cond [ + (eq_attr "type" "lddw") (const_int 16) + ] (const_int 8))) + +;; Describe a user's asm statement. +(define_asm_attributes + [(set_attr "type" "multi")]) + +;;;; Mode attributes and iterators + +(define_mode_attr mop [(QI "b") (HI "h") (SI "w") (DI "dw") + (SF "w") (DF "dw")]) +(define_mode_attr mtype [(SI "alu32") (DI "alu")]) +(define_mode_attr msuffix [(SI "32") (DI "")]) + +;;;; NOPs + +(define_insn "nop" + [(const_int 0)] + "" + "mov\t%%r0,%%r0" + [(set_attr "type" "alu")]) + +;;;; Arithmetic/Logical + +;; The arithmetic and logic operations below are defined for SI and DI +;; modes. The mode iterator AM is used in order to expand to two +;; insns, with the proper modes. +;; +;; 32-bit arithmetic (for SI modes) is implemented using the alu32 +;; instructions. + +(define_mode_iterator AM [SI DI]) + +;;; Addition +(define_insn "add3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (plus:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" " r,I")))] + "1" + "add\t%0,%2" + [(set_attr "type" "")]) + +;;; Subtraction + +;; Note that subtractions of constants become additions, so there is +;; no need to handle immediate operands in the subMODE3 insns. + +(define_insn "sub3" + [(set (match_operand:AM 0 "register_operand" "=r") + (minus:AM (match_operand:AM 1 "register_operand" " 0") + (match_operand:AM 2 "register_operand" " r")))] + "" + "sub\t%0,%2" + [(set_attr "type" "")]) + +;;; Negation +(define_insn "neg2" + [(set (match_operand:AM 0 "register_operand" "=r") + (neg:AM (match_operand:AM 1 "register_operand" " 0")))] + "" + "neg\t%0" + [(set_attr "type" "")]) + +;;; Multiplication +(define_insn "mul3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (mult:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" " r,I")))] + "" + "mul\t%0,%2" + [(set_attr "type" "")]) + +(define_insn "*mulsidi3_zeroextend" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI + (mult:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "reg_or_imm_operand" "r,I"))))] + "" + "mul32\t%0,%2" + [(set_attr "type" "alu32")]) + +;;; Division + +;; Note that eBPF doesn't provide instructions for signed integer +;; division. + +(define_insn "udiv3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (udiv:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "div\t%0,%2" + [(set_attr "type" "")]) + +;;; Modulus + +;; Note that eBPF doesn't provide instructions for signed integer +;; remainder. + +(define_insn "umod3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (umod:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "mod\t%0,%2" + [(set_attr "type" "")]) + +;;; Logical AND +(define_insn "and3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (and:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "and\t%0,%2" + [(set_attr "type" "")]) + +;;; Logical inclusive-OR +(define_insn "ior3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (ior:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "or\t%0,%2" + [(set_attr "type" "")]) + +;;; Logical exclusive-OR +(define_insn "xor3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (xor:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "xor\t%0,%2" + [(set_attr "type" "")]) + +;;;; Conversions + +;;; Zero-extensions + +;; For register operands smaller than 32-bit zero-extending is +;; achieved ANDing the value in the source register to a suitable +;; mask. +;; +;; For register operands bigger or equal than 32-bit, we generate a +;; mov32 instruction to zero the high 32-bits of the destination +;; register. +;; +;; For memory operands, of any width, zero-extending is achieved using +;; the ldx{bhwdw} instructions to load the values in registers. + +(define_insn "zero_extendhidi2" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] + "" + "@ + and\t%0,0xffff + ldxh\t%0,%1" + [(set_attr "type" "alu,ldx")]) + +(define_insn "zero_extendqidi2" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] + "" + "@ + and\t%0,0xff + ldxb\t%0,%1" + [(set_attr "type" "alu,ldx")]) + +(define_insn "zero_extendsidi2" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI + (match_operand:SI 1 "nonimmediate_operand" "r,m")))] + "" + "@ + mov32\t%0,%1 + ldxw\t%0,%1" + [(set_attr "type" "alu,ldx")]) + +;;; Sign-extension + +;; Sign-extending a 32-bit value into a 64-bit value is achieved using +;; shifting, with instructions generated by the expand below. + +(define_expand "extendsidi2" + [(set (match_operand:DI 0 "register_operand") + (sign_extend:DI (match_operand:SI 1 "register_operand")))] + "" +{ + operands[1] = gen_lowpart (DImode, operands[1]); + emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (32))); + emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32))); + DONE; +}) + +;;;; Data movement + +(define_mode_iterator MM [QI HI SI DI SF DF]) + +(define_expand "mov" + [(set (match_operand:MM 0 "general_operand") + (match_operand:MM 1 "general_operand"))] + "" + " +{ + if (!register_operand(operands[0], mode) + && !register_operand(operands[1], mode)) + operands[1] = force_reg (mode, operands[1]); +}") + +(define_insn "*mov" + [(set (match_operand:MM 0 "nonimmediate_operand" "=r, r,r,m,m") + (match_operand:MM 1 "mov_src_operand" " m,rI,B,r,I"))] + "" + "@ + ldx\t%0,%1 + mov\t%0,%1 + lddw\t%0,%1 + stx\t%0,%1 + st\t%0,%1" +[(set_attr "type" "ldx,alu,alu,stx,st")]) + +;;;; Shifts + +(define_mode_iterator SIM [SI DI]) + +(define_insn "ashr3" + [(set (match_operand:SIM 0 "register_operand" "=r,r") + (ashiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0") + (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] + "" + "arsh\t%0,%2" + [(set_attr "type" "")]) + +(define_insn "ashl3" + [(set (match_operand:SIM 0 "register_operand" "=r,r") + (ashift:SIM (match_operand:SIM 1 "register_operand" " 0,0") + (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] + "" + "lsh\t%0,%2" + [(set_attr "type" "")]) + +(define_insn "lshr3" + [(set (match_operand:SIM 0 "register_operand" "=r,r") + (lshiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0") + (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] + "" + "rsh\t%0,%2" + [(set_attr "type" "")]) + +;;;; Conditional branches + +;; The eBPF jump instructions use 64-bit arithmetic when evaluating +;; the jump conditions. Therefore we use DI modes below. + +(define_expand "cbranchdi4" + [(set (pc) + (if_then_else (match_operator 0 "comparison_operator" + [(match_operand:DI 1 "register_operand") + (match_operand:DI 2 "reg_or_imm_operand")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" +{ + if (!ordered_comparison_operator (operands[0], VOIDmode)) + FAIL; +}) + +(define_insn "*branch_on_di" + [(set (pc) + (if_then_else (match_operator 3 "ordered_comparison_operator" + [(match_operand:DI 0 "register_operand" "r") + (match_operand:DI 1 "reg_or_imm_operand" "rI")]) + (label_ref (match_operand 2 "" "")) + (pc)))] + "" +{ + int code = GET_CODE (operands[3]); + + switch (code) + { + case EQ: return "jeq\t%0,%1,%2"; break; + case NE: return "jne\t%0,%1,%2"; break; + case LT: return "jslt\t%0,%1,%2"; break; + case LE: return "jsle\t%0,%1,%2"; break; + case GT: return "jsgt\t%0,%1,%2"; break; + case GE: return "jsge\t%0,%1,%2"; break; + case LTU: return "jlt\t%0,%1,%2"; break; + case LEU: return "jle\t%0,%1,%2"; break; + case GTU: return "jgt\t%0,%1,%2"; break; + case GEU: return "jge\t%0,%1,%2"; break; + default: + gcc_unreachable (); + return ""; + } +} + [(set_attr "type" "jmp")]) + +;;;; Unconditional branches + +(define_insn "jump" + [(set (pc) + (label_ref (match_operand 0 "" "")))] + "" + "ja\t%0" +[(set_attr "type" "jmp")]) + +;;;; Function prologue/epilogue + +(define_insn "exit" + [(simple_return)] + "" + "exit" + [(set_attr "type" "jmp")]) + +(define_expand "prologue" + [(const_int 0)] + "" +{ + bpf_expand_prologue (); + DONE; +}) + +(define_expand "epilogue" + [(const_int 0)] + "" +{ + bpf_expand_epilogue (); + DONE; +}) + +;;;; Function calls + +(define_expand "call" + [(parallel [(call (match_operand 0 "") + (match_operand 1 "")) + (use (match_operand 2 "")) ;; next_arg_reg + (use (match_operand 3 ""))])] ;; struct_value_size_rtx + "" +{ + rtx target = XEXP (operands[0], 0); + emit_call_insn (gen_call_internal (target, operands[1])); + DONE; +}) + +(define_insn "call_internal" + [(call (mem:DI (match_operand:DI 0 "call_operand" "Sr")) + (match_operand:SI 1 "general_operand" ""))] + ;; operands[2] is next_arg_register + ;; operands[3] is struct_value_size_rtx. + "" + { return bpf_output_call (operands[0]); } + [(set_attr "type" "jmp")]) + +(define_expand "call_value" + [(parallel [(set (match_operand 0 "") + (call (match_operand 1 "") + (match_operand 2 ""))) + (use (match_operand 3 ""))])] ;; next_arg_reg + "" +{ + rtx target = XEXP (operands[1], 0); + emit_call_insn (gen_call_value_internal (operands[0], target, + operands[2])); + DONE; +}) + +(define_insn "call_value_internal" + [(set (match_operand 0 "register_operand" "") + (call (mem:DI (match_operand:DI 1 "call_operand" "Sr")) + (match_operand:SI 2 "general_operand" "")))] + ;; operands[3] is next_arg_register + ;; operands[4] is struct_value_size_rtx. + "" + { return bpf_output_call (operands[1]); } + [(set_attr "type" "jmp")]) + +(define_insn "sibcall" + [(call (label_ref (match_operand 0 "" "")) + (match_operand:SI 1 "general_operand" ""))] + ;; operands[2] is next_arg_register + ;; operands[3] is struct_value_size_rtx. + "" + "ja\t%0" + [(set_attr "type" "jmp")]) + +;;;; Non-generic load instructions + +(define_mode_iterator LDM [QI HI SI DI]) +(define_mode_attr ldop [(QI "b") (HI "h") (SI "w") (DI "dw")]) + +(define_insn "ldind" + [(set (reg:LDM R0_REGNUM) + (unspec:LDM [(match_operand:DI 0 "register_operand" "r") + (match_operand:SI 1 "imm32_operand" "I")] + UNSPEC_LDINDABS)) + (clobber (reg:DI R1_REGNUM)) + (clobber (reg:DI R2_REGNUM)) + (clobber (reg:DI R3_REGNUM)) + (clobber (reg:DI R4_REGNUM))] + "" + "ldind\t%0,%1" + [(set_attr "type" "ld")]) + +(define_insn "ldabs" + [(set (reg:LDM R0_REGNUM) + (unspec:LDM [(match_operand:SI 0 "imm32_operand" "I") + (match_operand:SI 1 "imm32_operand" "I")] + UNSPEC_LDINDABS)) + (clobber (reg:DI R1_REGNUM)) + (clobber (reg:DI R2_REGNUM)) + (clobber (reg:DI R3_REGNUM)) + (clobber (reg:DI R4_REGNUM))] + "" + "ldabs\t%0" + [(set_attr "type" "ld")]) + +;;;; Atomic increments + +(define_mode_iterator AMO [SI DI]) + +(define_insn "atomic_add" + [(set (match_operand:AMO 0 "memory_operand" "+m") + (unspec_volatile:AMO + [(plus:AMO (match_dup 0) + (match_operand:AMO 1 "register_operand" "r")) + (match_operand:SI 2 "const_int_operand")] ;; Memory model. + UNSPEC_XADD))] + "" + "xadd\t%0,%1" + [(set_attr "type" "xadd")]) diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt new file mode 100644 index 00000000000..e61cf953c15 --- /dev/null +++ b/gcc/config/bpf/bpf.opt @@ -0,0 +1,123 @@ +; Options for the eBPF compiler port. + +; Copyright (C) 2019 Free Software Foundation, Inc. +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY +; WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +; for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; . + +HeaderInclude +config/bpf/bpf-opts.h + +; Selecting the kind of kernel the eBPF will be running on. + +mkernel= +Target RejectNegative Joined Var(bpf_kernel) Enum(bpf_kernel) Init(LINUX_LATEST) +Generate eBPF for the given Linux kernel version. + +Enum +Name(bpf_kernel) Type(enum bpf_kernel_version) + +EnumValue +Enum(bpf_kernel) String(native) Value(LINUX_NATIVE) DriverOnly + +EnumValue +Enum(bpf_kernel) String(latest) Value(LINUX_LATEST) DriverOnly + +EnumValue +Enum(bpf_kernel) String(4.0) Value(LINUX_V4_0) + +EnumValue +Enum(bpf_kernel) String(4.1) Value(LINUX_V4_1) + +EnumValue +Enum(bpf_kernel) String(4.2) Value(LINUX_V4_2) + +EnumValue +Enum(bpf_kernel) String(4.3) Value(LINUX_V4_3) + +EnumValue +Enum(bpf_kernel) String(4.4) Value(LINUX_V4_4) + +EnumValue +Enum(bpf_kernel) String(4.5) Value(LINUX_V4_5) + +EnumValue +Enum(bpf_kernel) String(4.6) Value(LINUX_V4_6) + +EnumValue +Enum(bpf_kernel) String(4.7) Value(LINUX_V4_7) + +EnumValue +Enum(bpf_kernel) String(4.8) Value(LINUX_V4_8) + +EnumValue +Enum(bpf_kernel) String(4.9) Value(LINUX_V4_9) + +EnumValue +Enum(bpf_kernel) String(4.10) Value(LINUX_V4_10) + +EnumValue +Enum(bpf_kernel) String(4.11) Value(LINUX_V4_11) + +EnumValue +Enum(bpf_kernel) String(4.12) Value(LINUX_V4_12) + +EnumValue +Enum(bpf_kernel) String(4.13) Value(LINUX_V4_13) + +EnumValue +Enum(bpf_kernel) String(4.14) Value(LINUX_V4_14) + +EnumValue +Enum(bpf_kernel) String(4.15) Value(LINUX_V4_15) + +EnumValue +Enum(bpf_kernel) String(4.16) Value(LINUX_V4_16) + +EnumValue +Enum(bpf_kernel) String(4.17) Value(LINUX_V4_17) + +EnumValue +Enum(bpf_kernel) String(4.18) Value(LINUX_V4_18) + +EnumValue +Enum(bpf_kernel) String(4.19) Value(LINUX_V4_19) + +EnumValue +Enum(bpf_kernel) String(4.20) Value(LINUX_V4_20) + +EnumValue +Enum(bpf_kernel) String(5.0) Value(LINUX_V5_0) + +EnumValue +Enum(bpf_kernel) String(5.1) Value(LINUX_V5_1) + +EnumValue +Enum(bpf_kernel) String(5.2) Value(LINUX_V5_2) + +; Selecting big endian or little endian targets. + +mbig-endian +Target RejectNegative Report Mask(BIG_ENDIAN) +Generate big-endian eBPF. + +mlittle-endian +Target RejectNegative Report InverseMask(BIG_ENDIAN) +Generate little-endian eBPF. + +mframe-limit= +Target Joined RejectNegative UInteger IntegerRange(0, 32767) Var(bpf_frame_limit) Init(512) +Set a hard limit for the size of each stack frame, in bytes. diff --git a/gcc/config/bpf/constraints.md b/gcc/config/bpf/constraints.md new file mode 100644 index 00000000000..f27b785d9ce --- /dev/null +++ b/gcc/config/bpf/constraints.md @@ -0,0 +1,32 @@ +;; Constraint definitions for eBPF. +;; Copyright (C) 2019 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_constraint "I" + "A 32-bit signed immediate." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, -1 - 0x7fffffff, 0x7fffffff)"))) + +(define_constraint "B" + "A constant argument for LDDW." + (match_code "const,symbol_ref,label_ref,const_double,const_int")) + +(define_constraint "S" + "A constant call address." + (match_code "const,symbol_ref,label_ref,const_int")) + diff --git a/gcc/config/bpf/predicates.md b/gcc/config/bpf/predicates.md new file mode 100644 index 00000000000..9ba0e785082 --- /dev/null +++ b/gcc/config/bpf/predicates.md @@ -0,0 +1,64 @@ +;; Predicate definitions for eBPF. +;; Copyright (C) 2019 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_predicate "reg_or_imm_operand" + (ior (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), -1 - 0x7fffffff, 0x7fffffff)")) + (match_operand 0 "register_operand"))) + +(define_predicate "imm32_operand" + (ior (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 0, 0xffffffff)")) + (match_code "symbol_ref,label_ref,const"))) + +(define_predicate "lddw_operand" + (match_code "symbol_ref,label_ref,const,const_double,const_int")) + +(define_predicate "call_operand" + (match_code "reg,symbol_ref,const_int,const") +{ + if (GET_CODE (op) == CONST) + { + op = XEXP (op, 0); + + switch (GET_CODE (op)) + { + case SYMBOL_REF: + case LABEL_REF: + case CONST_INT: + return true; + break; + default: + break; + } + + return false; + } + + return true; +}) + +(define_predicate "mov_src_operand" + (ior (match_operand 0 "memory_operand") + (match_operand 0 "reg_or_imm_operand") + (match_operand 0 "lddw_operand"))) + +(define_predicate "register_compare_operator" + (match_code "eq,ne,geu,gtu,ge,gt")) + diff --git a/gcc/config/bpf/t-bpf b/gcc/config/bpf/t-bpf new file mode 100644 index 00000000000..e69de29bb2d diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a922f5ca77a..64fccfe9b87 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13549,6 +13549,8 @@ instructions, but allow the compiler to schedule those calls. * ARM ARMv8-M Security Extensions:: * AVR Built-in Functions:: * Blackfin Built-in Functions:: +* BPF Built-in Functions:: +* BPF Kernel Helpers:: * FR-V Built-in Functions:: * MIPS DSP Built-in Functions:: * MIPS Paired-Single Support:: @@ -14545,6 +14547,175 @@ void __builtin_bfin_csync (void) void __builtin_bfin_ssync (void) @end smallexample +@node BPF Built-in Functions +@subsection BPF Built-in Functions + +The following built-in functions are available for eBPF targets. + +@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_byte (unsigned long long @var{offset}) +Load a byte from the @code{struct sk_buff} packet data pointed by the register @code{%r6} and return it. +@end deftypefn + +@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_half (unsigned long long @var{offset}) +Load 16-bits from the @code{struct sk_buff} packet data pointed by the register @code{%r6} and return it. +@end deftypefn + +@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_word (unsigned long long @var{offset}) +Load 32-bits from the @code{struct sk_buff} packet data pointed by the register @code{%r6} and return it. +@end deftypefn + +@node BPF Kernel Helpers +@subsection BPF Kernel Helpers + +These built-in functions are available for calling kernel helpers, and +they are available depending on the kernel version selected as the +CPU. + +Rather than using the built-ins directly, it is preferred for programs +to include @file{bpf-helpers.h} and use the wrappers defined there. + +For a full description of what the helpers do, the arguments they +take, and the returned value, see the +@file{linux/include/uapi/linux/bpf.h} in a Linux source tree. + +@smallexample +void *__builtin_bpf_helper_map_lookup_elem (void *map, void *key) +int __builtin_bpf_helper_map_update_elem (void *map, void *key, + void *value, + unsigned long long flags) +int __builtin_bpf_helper_map_delete_elem (void *map, const void *key) +int __builtin_bpf_helper_map_push_elem (void *map, const void *value, + unsigned long long flags) +int __builtin_bpf_helper_map_pop_elem (void *map, void *value) +int __builtin_bpf_helper_map_peek_elem (void *map, void *value) +int __builtin_bpf_helper_clone_redirect (void *skb, + unsigned int ifindex, + unsigned long long flags) +int __builtin_bpf_helper_skb_get_tunnel_key (void *ctx, void *key, int size, int flags) +int __builtin_bpf_helper_skb_set_tunnel_key (void *ctx, void *key, int size, int flags) +int __builtin_bpf_helper_skb_get_tunnel_opt (void *ctx, void *md, int size) +int __builtin_bpf_helper_skb_set_tunnel_opt (void *ctx, void *md, int size) +int __builtin_bpf_helper_skb_get_xfrm_state (void *ctx, int index, void *state, + int size, int flags) +static unsigned long long __builtin_bpf_helper_skb_cgroup_id (void *ctx) +static unsigned long long __builtin_bpf_helper_skb_ancestor_cgroup_id + (void *ctx, int level) +int __builtin_bpf_helper_skb_vlan_push (void *ctx, __be16 vlan_proto, __u16 vlan_tci) +int __builtin_bpf_helper_skb_vlan_pop (void *ctx) +int __builtin_bpf_helper_skb_ecn_set_ce (void *ctx) + +int __builtin_bpf_helper_skb_load_bytes (void *ctx, int off, void *to, int len) +int __builtin_bpf_helper_skb_load_bytes_relative (void *ctx, int off, void *to, int len, __u32 start_header) +int __builtin_bpf_helper_skb_store_bytes (void *ctx, int off, void *from, int len, int flags) +int __builtin_bpf_helper_skb_under_cgroup (void *ctx, void *map, int index) +int __builtin_bpf_helper_skb_change_head (void *, int len, int flags) +int __builtin_bpf_helper_skb_pull_data (void *, int len) +int __builtin_bpf_helper_skb_change_proto (void *ctx, __be16 proto, __u64 flags) +int __builtin_bpf_helper_skb_change_type (void *ctx, __u32 type) +int __builtin_bpf_helper_skb_change_tail (void *ctx, __u32 len, __u64 flags) +int __builtin_bpf_helper_skb_adjust_room (void *ctx, __s32 len_diff, __u32 mode, + unsigned long long flags) +@end smallexample + +Other helpers: + +@smallexample +int __builtin_bpf_helper_probe_read (void *dst, unsigned int size, void *src) +unsigned long long __builtin_bpf_helper_ktime_get_ns (void) +int __builtin_bpf_helper_trace_printk (const char *fmt, unsigned int fmt_size, ...) +void __builtin_bpf_helper_tail_call (void *ctx, void *prog_array_map, unsigned int index) +unsigned int __builtin_bpf_helper_get_smp_processor_id (void) +unsigned long long __builtin_bpf_helper_get_current_pid_tgid (void) +unsigned long long __builtin_bpf_helper_get_current_uid_gid (void) +int __builtin_bpf_helper_get_current_comm (void *buf, unsigned int size_of_buf) +unsigned long long __builtin_bpf_helper_perf_event_read (void *map, unsigned long long flags) + +int __builtin_bpf_helper_redirect (unsigned int ifindex, unsigned long long flags) +int __builtin_bpf_helper_redirect_map (void *map, unsigned int key, unsigned long long flags) +int __builtin_bpf_helper_perf_event_output (void *ctx,void *map, unsigned long long flags, void *data, unsigned long long size) +int __builtin_bpf_helper_get_stackid (void *ctx, void *map, unsigned long long flags) +int __builtin_bpf_helper_probe_write_user (void *dst, const void *src, unsigned int len) +int __builtin_bpf_helper_current_task_under_cgroup (void *map, unsigned int index) + +static unsigned long long __builtin_bpf_helper_get_prandom_u32 (void) +int __builtin_bpf_helper_xdp_adjust_head (void *ctx, int offset) +int __builtin_bpf_helper_xdp_adjust_meta (void *ctx, int offset) +int __builtin_bpf_helper_get_socket_cookie (void *ctx) +int __builtin_bpf_helper_setsockopt (void *ctx, int level, int optname, void *optval, + int optlen) +int __builtin_bpf_helper_getsockopt (void *ctx, int level, int optname, void *optval, + int optlen) +int __builtin_bpf_helper_sock_ops_cb_flags_set (void *ctx, int flags) +int __builtin_bpf_helper_sk_redirect_map (void *ctx, void *map, int key, int flags) +int __builtin_bpf_helper_sk_redirect_hash (void *ctx, void *map, void *key, int flags) +int __builtin_bpf_helper_sock_map_update (void *map, void *key, void *value, + unsigned long long flags) +int __builtin_bpf_helper_sock_hash_update (void *map, void *key, void *value, + unsigned long long flags) +int __builtin_bpf_helper_perf_event_read_value (void *map, unsigned long long flags, + void *buf, unsigned int buf_size) +int __builtin_bpf_helper_perf_prog_read_value (void *ctx, void *buf, + unsigned int buf_size) + +int __builtin_bpf_helper_override_return (void *ctx, unsigned long rc) +int __builtin_bpf_helper_msg_redirect_map (void *ctx, void *map, int key, int flags) +int __builtin_bpf_helper_msg_redirect_hash (void *ctx, + void *map, void *key, int flags) +int __builtin_bpf_helper_msg_apply_bytes (void *ctx, int len) +int __builtin_bpf_helper_msg_cork_bytes (void *ctx, int len) +int __builtin_bpf_helper_msg_pull_data (void *ctx, int start, int end, int flags) +int __builtin_bpf_helper_msg_push_data (void *ctx, int start, int end, int flags) +int __builtin_bpf_helper_msg_pop_data (void *ctx, int start, int cut, int flags) +int __builtin_bpf_helper_bind (void *ctx, void *addr, int addr_len) +int __builtin_bpf_helper_xdp_adjust_tail (void *ctx, int offset) +int __builtin_bpf_helper_sk_select_reuseport (void *ctx, void *map, void *key, __u32 flags) +int __builtin_bpf_helper_get_stack (void *ctx, void *buf, int size, int flags) +int __builtin_bpf_helper_fib_lookup (void *ctx, struct bpf_fib_lookup *params, + int plen, __u32 flags) + +int __builtin_bpf_helper_lwt_push_encap (void *ctx, unsigned int type, void *hdr, + unsigned int len) +int __builtin_bpf_helper_lwt_seg6_store_bytes (void *ctx, unsigned int offset, + void *from, unsigned int len) +int __builtin_bpf_helper_lwt_seg6_action (void *ctx, unsigned int action, void *param, + unsigned int param_len) +int __builtin_bpf_helper_lwt_seg6_adjust_srh (void *ctx, unsigned int offset, + unsigned int len) +int __builtin_bpf_helper_rc_repeat (void *ctx) +int __builtin_bpf_helper_rc_keydown (void *ctx, unsigned int protocol, + unsigned long long scancode, unsigned int toggle) +static unsigned long long __builtin_bpf_helper_get_current_cgroup_id (void) +static void *__builtin_bpf_helper_get_local_storage (void *map, unsigned long long flags) +static struct bpf_sock *__builtin_bpf_helper_sk_lookup_tcp (void *ctx, void *tuple, int size, unsigned long long netns_id, unsigned long long flags) +static struct bpf_sock *__builtin_bpf_helper_sk_lookup_udp (void *ctx, void *tuple, int size, unsigned long long netns_id, unsigned long long flags) +int __builtin_bpf_helper_sk_release (struct bpf_sock *sk) +int __builtin_bpf_helper_rc_pointer_rel (void *ctx, int rel_x, int rel_y) +static void __builtin_bpf_helper_spin_lock (struct bpf_spin_lock *lock) +static void __builtin_bpf_helper_spin_unlock (struct bpf_spin_lock *lock) + +static struct bpf_sock *__builtin_bpf_helper_sk_fullsock (struct bpf_sock *sk) +static struct bpf_tcp_sock *__builtin_bpf_helper_tcp_sock (struct bpf_sock *sk) +static struct bpf_sock *__builtin_bpf_helper_get_listener_sock (struct bpf_sock *sk) + +int __builtin_bpf_helper_l3_csum_replace (void *ctx, int off, int from, int to, int flags) +int __builtin_bpf_helper_l4_csum_replace (void *ctx, int off, int from, int to, int flags) +int __builtin_bpf_helper_csum_diff (void *from, int from_size, void *to, int to_size, int seed) + +static unsigned int __builtin_bpf_helper_get_cgroup_classid (void *ctx) +static unsigned int __builtin_bpf_helper_get_route_realm (void *ctx) +static unsigned int __builtin_bpf_helper_get_hash_recalc (void *ctx) +static unsigned long long __builtin_bpf_helper_get_current_task (void *ctx) + +static long long __builtin_bpf_helper_csum_update (void *ctx, __u32 csum) +static void __builtin_bpf_helper_set_hash_invalid (void *ctx) +int __builtin_bpf_helper_get_numa_node_id (void) +int __builtin_bpf_helper_probe_read_str (void *ctx, __u32 size, + const void *unsafe_ptr) +static unsigned int __builtin_bpf_helper_get_socket_uid (void *ctx) +static unsigned int __builtin_bpf_helper_set_hash (void *ctx, __u32 hash) +@end smallexample + + @node FR-V Built-in Functions @subsection FR-V Built-in Functions diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index bfcd76e47bd..7bcdfcbca15 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -802,6 +802,10 @@ Objective-C and Objective-C++ Dialects}. -msmall-text -mlarge-text @gol -mmemory-latency=@var{time}} +@emph{eBPF Options} +@gccoptlist{-mbig-endian -mlittle-endian -mkernel=@var{version} +-mframe-limit=@var{bytes}} + @emph{FR30 Options} @gccoptlist{-msmall-model -mno-lsim} @@ -15650,6 +15654,7 @@ platform. * C-SKY Options:: * Darwin Options:: * DEC Alpha Options:: +* eBPF Options:: * FR30 Options:: * FT32 Options:: * FRV Options:: @@ -19771,6 +19776,38 @@ Note that L3 is only valid for EV5. @end table @end table +@node eBPF Options +@subsection eBPF Options +@cindex eBPF Options + +@table @gcctabopt +@item -mframe-limit=@var{bytes} +This specifies the hard limit for frame sizes, in bytes. Currently, +the value that can be specified should be less than or equal to +@samp{32767}. Defaults to whatever limit is imposed by the version of +the Linux kernel targeted. + +@item -mkernel=@var{version} +@opindex mkernel +This specifies the minimum version of the kernel that will run the +compiled program. GCC uses this version to determine which +instructions to use, what kernel helpers to allow, etc. Currently, +@var{version} can be one of @samp{4.0}, @samp{4.1}, @samp{4.2}, +@samp{4.3}, @samp{4.4}, @samp{4.5}, @samp{4.6}, @samp{4.7}, +@samp{4.8}, @samp{4.9}, @samp{4.10}, @samp{4.11}, @samp{4.12}, +@samp{4.13}, @samp{4.14}, @samp{4.15}, @samp{4.16}, @samp{4.17}, +@samp{4.18}, @samp{4.19}, @samp{4.20}, @samp{5.0}, @samp{5.1}, +@samp{5.2}, @samp{latest} and @samp{native}. + +@item -mbig-endian +@opindex mbig-endian +Generate code for a big-endian target. + +@item -mlittle-endian +@opindex mlittle-endian +Generate code for a little-endian target. This is the default. +@end table + @node FR30 Options @subsection FR30 Options @cindex FR30 Options diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9533da6e819..faa487f51cd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,218 @@ +2019-09-09 Jose E. Marchesi + + * gcc.dg/builtins-config.h: eBPF doesn't support C99 standard + functions. + * gcc.c-torture/compile/20101217-1.c: Add a function prototype for + printf. + * gcc.c-torture/compile/20000211-1.c: Skip if target bpf-*-*. + * gcc.c-torture/compile/poor.c: Likewise. + * gcc.c-torture/compile/pr25311.c: Likewise. + * gcc.c-torture/compile/pr39928-1.c: Likewise. + * gcc.c-torture/compile/pr70061.c: Likewise. + * gcc.c-torture/compile/920501-7.c: Likewise. + * gcc.c-torture/compile/20000403-1.c: Likewise. + * gcc.c-torture/compile/20001226-1.c: Likewise. + * gcc.c-torture/compile/20030903-1.c: Likewise. + * gcc.c-torture/compile/20031125-1.c: Likewise. + * gcc.c-torture/compile/20040101-1.c: Likewise. + * gcc.c-torture/compile/20040317-2.c: Likewise. + * gcc.c-torture/compile/20040726-1.c: Likewise. + * gcc.c-torture/compile/20051216-1.c: Likewise. + * gcc.c-torture/compile/900313-1.c: Likewise. + * gcc.c-torture/compile/920625-1.c: Likewise. + * gcc.c-torture/compile/930421-1.c: Likewise. + * gcc.c-torture/compile/930623-1.c: Likewise. + * gcc.c-torture/compile/961004-1.c: Likewise. + * gcc.c-torture/compile/980504-1.c: Likewise. + * gcc.c-torture/compile/980816-1.c: Likewise. + * gcc.c-torture/compile/990625-1.c: Likewise. + * gcc.c-torture/compile/DFcmp.c: Likewise. + * gcc.c-torture/compile/HIcmp.c: Likewise. + * gcc.c-torture/compile/HIset.c: Likewise. + * gcc.c-torture/compile/QIcmp.c: Likewise. + * gcc.c-torture/compile/QIset.c: Likewise. + * gcc.c-torture/compile/SFset.c: Likewise. + * gcc.c-torture/compile/SIcmp.c: Likewise. + * gcc.c-torture/compile/SIset.c: Likewise. + * gcc.c-torture/compile/UHIcmp.c: Likewise. + * gcc.c-torture/compile/UQIcmp.c: Likewise. + * gcc.c-torture/compile/USIcmp.c: Likewise. + * gcc.c-torture/compile/consec.c: Likewise. + * gcc.c-torture/compile/limits-fndefn.c: Likewise. + * gcc.c-torture/compile/lll.c: Likewise. + * gcc.c-torture/compile/parms.c: Likewise. + * gcc.c-torture/compile/pass.c: Likewise. + * gcc.c-torture/compile/pp.c: Likewise. + * gcc.c-torture/compile/pr32399.c: Likewise. + * gcc.c-torture/compile/pr34091.c: Likewise. + * gcc.c-torture/compile/pr34688.c: Likewise. + * gcc.c-torture/compile/pr37258.c: Likewise. + * gcc.c-torture/compile/pr37327.c: Likewise. + * gcc.c-torture/compile/pr37381.c: Likewise. + * gcc.c-torture/compile/pr37669-2.c: Likewise. + * gcc.c-torture/compile/pr37669.c: Likewise. + * gcc.c-torture/compile/pr37742-3.c: Likewise. + * gcc.c-torture/compile/pr44063.c: Likewise. + * gcc.c-torture/compile/pr48596.c: Likewise. + * gcc.c-torture/compile/pr51856.c: Likewise. + * gcc.c-torture/compile/pr54428.c: Likewise. + * gcc.c-torture/compile/pr54713-1.c: Likewise. + * gcc.c-torture/compile/pr54713-2.c: Likewise. + * gcc.c-torture/compile/pr54713-3.c: Likewise. + * gcc.c-torture/compile/pr55921.c: Likewise. + * gcc.c-torture/compile/pr70240.c: Likewise. + * gcc.c-torture/compile/pr70355.c: Likewise. + * gcc.c-torture/compile/pr82052.c: Likewise. + * gcc.c-torture/compile/pr83487.c: Likewise. + * gcc.c-torture/compile/pr86122.c: Likewise. + * gcc.c-torture/compile/pret-arg.c: Likewise. + * gcc.c-torture/compile/regs-arg-size.c: Likewise. + * gcc.c-torture/compile/structret.c: Likewise. + * gcc.c-torture/compile/uuarg.c: Likewise. + * gcc.dg/20001009-1.c: Likewise. + * gcc.dg/20020418-1.c: Likewise. + * gcc.dg/20020426-2.c: Likewise. + * gcc.dg/20020430-1.c: Likewise. + * gcc.dg/20040306-1.c: Likewise. + * gcc.dg/20040622-2.c: Likewise. + * gcc.dg/20050603-2.c: Likewise. + * gcc.dg/20050629-1.c: Likewise. + * gcc.dg/20061026.c: Likewise. + * gcc.dg/Warray-bounds-3.c: Likewise. + * gcc.dg/Warray-bounds-30.c: Likewise. + * gcc.dg/Wframe-larger-than-2.c: Likewise. + * gcc.dg/Wframe-larger-than.c: Likewise. + * gcc.dg/Wrestrict-11.c: Likewise. + * gcc.c-torture/compile/20000804-1.c: Likewise. + +2019-09-09 Jose E. Marchesi + + * lib/target-supports.exp (check_effective_target_trampolines): + Adapt to eBPF. + (check_effective_target_indirect_jumps): Likewise. + (check_effective_target_nonlocal_goto): Likewise. + (check_effective_target_global_constructor): Likewise. + (check_effective_target_return_address): Likewise. + +2019-09-09 Jose E. Marchesi + + * gcc.target/bpf/bpf.exp: New file. + * gcc.target/bpf/builtin-load.c: Likewise. + * cc.target/bpf/constant-calls.c: Likewise. + * gcc.target/bpf/diag-funargs.c: Likewise. + * gcc.target/bpf/diag-funargs-2.c: Likewise. + * gcc.target/bpf/diag-funargs-3.c: Likewise. + * gcc.target/bpf/diag-indcalls.c: Likewise. + * gcc.target/bpf/helper-bind.c: Likewise. + * cc.target/bpf/helper-bpf-redirect.c: Likewise. + * gcc.target/bpf/helper-clone-redirect.c: Likewise. + * gcc.target/bpf/helper-csum-diff.c: Likewise. + * gcc.target/bpf/helper-csum-update.c: Likewise. + * gcc.target/bpf/helper-current-task-under-cgroup.c: Likewise. + * gcc.target/bpf/helper-fib-lookup.c: Likewise. + * gcc.target/bpf/helper-get-cgroup-classid.c: Likewise. + * gcc.target/bpf/helper-get-current-cgroup-id.c: Likewise. + * gcc.target/bpf/helper-get-current-comm.c: Likewise. + * gcc.target/bpf/helper-get-current-pid-tgid.c: Likewise. + * gcc.target/bpf/helper-get-current-task.c: Likewise. + * gcc.target/bpf/helper-get-current-uid-gid.c: Likewise. + * gcc.target/bpf/helper-get-hash-recalc.c: Likewise. + * gcc.target/bpf/helper-get-listener-sock.c: Likewise. + * gcc.target/bpf/helper-get-local-storage.c: Likewise. + * gcc.target/bpf/helper-get-numa-node-id.c: Likewise. + * gcc.target/bpf/helper-get-prandom-u32.c: Likewise. + * gcc.target/bpf/helper-get-route-realm.c: Likewise. + * gcc.target/bpf/helper-get-smp-processor-id.c: Likewise. + * gcc.target/bpf/helper-get-socket-cookie.c: Likewise. + * gcc.target/bpf/helper-get-socket-uid.c: Likewise. + * gcc.target/bpf/helper-getsockopt.c: Likewise. + * gcc.target/bpf/helper-get-stack.c: Likewise. + * gcc.target/bpf/helper-get-stackid.c: Likewise. + * gcc.target/bpf/helper-ktime-get-ns.c: Likewise. + * gcc.target/bpf/helper-l3-csum-replace.c: Likewise. + * gcc.target/bpf/helper-l4-csum-replace.c: Likewise. + * gcc.target/bpf/helper-lwt-push-encap.c: Likewise. + * gcc.target/bpf/helper-lwt-seg6-action.c: Likewise. + * gcc.target/bpf/helper-lwt-seg6-adjust-srh.c: Likewise. + * gcc.target/bpf/helper-lwt-seg6-store-bytes.c: Likewise. + * gcc.target/bpf/helper-map-delete-elem.c: Likewise. + * gcc.target/bpf/helper-map-lookup-elem.c: Likewise. + * gcc.target/bpf/helper-map-peek-elem.c: Likewise. + * gcc.target/bpf/helper-map-pop-elem.c: Likewise. + * gcc.target/bpf/helper-map-push-elem.c: Likewise. + * gcc.target/bpf/helper-map-update-elem.c: Likewise. + * gcc.target/bpf/helper-msg-apply-bytes.c: Likewise. + * gcc.target/bpf/helper-msg-cork-bytes.c: Likewise. + * gcc.target/bpf/helper-msg-pop-data.c: Likewise. + * gcc.target/bpf/helper-msg-pull-data.c: Likewise. + * gcc.target/bpf/helper-msg-push-data.c: Likewise. + * gcc.target/bpf/helper-msg-redirect-hash.c: Likewise. + * gcc.target/bpf/helper-msg-redirect-map.c: Likewise. + * gcc.target/bpf/helper-override-return.c: Likewise. + * gcc.target/bpf/helper-perf-event-output.c: Likewise. + * gcc.target/bpf/helper-perf-event-read.c: Likewise. + * gcc.target/bpf/helper-perf-event-read-value.c: Likewise. + * gcc.target/bpf/helper-perf-prog-read-value.c: Likewise. + * gcc.target/bpf/helper-probe-read.c: Likewise. + * gcc.target/bpf/helper-probe-read-str.c: Likewise. + * gcc.target/bpf/helper-probe-write-user.c: Likewise. + * gcc.target/bpf/helper-rc-keydown.c: Likewise. + * gcc.target/bpf/helper-rc-pointer-rel.c: Likewise. + * gcc.target/bpf/helper-rc-repeat.c: Likewise. + * gcc.target/bpf/helper-redirect-map.c: Likewise. + * gcc.target/bpf/helper-set-hash.c: Likewise. + * gcc.target/bpf/helper-set-hash-invalid.c: Likewise. + * gcc.target/bpf/helper-setsockopt.c: Likewise. + * gcc.target/bpf/helper-skb-adjust-room.c: Likewise. + * gcc.target/bpf/helper-skb-cgroup-id.c: Likewise. + * gcc.target/bpf/helper-skb-change-head.c: Likewise. + * gcc.target/bpf/helper-skb-change-proto.c: Likewise. + * gcc.target/bpf/helper-skb-change-tail.c: Likewise. + * gcc.target/bpf/helper-skb-change-type.c: Likewise. + * gcc.target/bpf/helper-skb-ecn-set-ce.c: Likewise. + * gcc.target/bpf/helper-skb-get-tunnel-key.c: Likewise. + * gcc.target/bpf/helper-skb-get-tunnel-opt.c: Likewise. + * gcc.target/bpf/helper-skb-get-xfrm-state.c: Likewise. + * gcc.target/bpf/helper-skb-load-bytes.c: Likewise. + * gcc.target/bpf/helper-skb-load-bytes-relative.c: Likewise. + * gcc.target/bpf/helper-skb-pull-data.c: Likewise. + * gcc.target/bpf/helper-skb-set-tunnel-key.c: Likewise. + * gcc.target/bpf/helper-skb-set-tunnel-opt.c: Likewise. + * gcc.target/bpf/helper-skb-store-bytes.c: Likewise. + * gcc.target/bpf/helper-skb-under-cgroup.c: Likewise. + * gcc.target/bpf/helper-skb-vlan-pop.c: Likewise. + * gcc.target/bpf/helper-skb-vlan-push.c: Likewise. + * gcc.target/bpf/helper-skc-lookup-tcp.c: Likewise. + * gcc.target/bpf/helper-sk-fullsock.c: Likewise. + * gcc.target/bpf/helper-sk-lookup-tcp.c: Likewise. + * gcc.target/bpf/helper-sk-lookup-upd.c: Likewise. + * gcc.target/bpf/helper-sk-redirect-hash.c: Likewise. + * gcc.target/bpf/helper-sk-redirect-map.c: Likewise. + * gcc.target/bpf/helper-sk-release.c: Likewise. + * gcc.target/bpf/helper-sk-select-reuseport.c: Likewise. + * gcc.target/bpf/helper-sk-storage-delete.c: Likewise. + * gcc.target/bpf/helper-sk-storage-get.c: Likewise. + * gcc.target/bpf/helper-sock-hash-update.c: Likewise. + * gcc.target/bpf/helper-sock-map-update.c: Likewise. + * gcc.target/bpf/helper-sock-ops-cb-flags-set.c: Likewise. + * gcc.target/bpf/helper-spin-lock.c: Likewise. + * gcc.target/bpf/helper-spin-unlock.c: Likewise. + * gcc.target/bpf/helper-strtol.c: Likewise. + * gcc.target/bpf/helper-strtoul.c: Likewise. + * gcc.target/bpf/helper-sysctl-get-current-value.c: Likewise. + * gcc.target/bpf/helper-sysctl-get-name.c: Likewise. + * gcc.target/bpf/helper-sysctl-get-new-value.c: Likewise. + * gcc.target/bpf/helper-sysctl-set-new-value.c: Likewise. + * gcc.target/bpf/helper-tail-call.c: Likewise. + * gcc.target/bpf/helper-tcp-check-syncookie.c: Likewise. + * gcc.target/bpf/helper-tcp-sock.c: Likewise. + * gcc.target/bpf/helper-trace-printk.c: Likewise. + * gcc.target/bpf/helper-xdp-adjust-head.c: Likewise. + * gcc.target/bpf/helper-xdp-adjust-meta.c: Likewise. + * gcc.target/bpf/helper-xdp-adjust-tail.c: Likewise. + * gcc.target/bpf/skb-ancestor-cgroup-id.c: Likewise. + * gcc.target/bpf/sync-fetch-and-add.c: Likewise. + 2019-09-09 Jose E. Marchesi * lib/target-supports.exp (check_effective_target_indirect_calls): diff --git a/gcc/testsuite/gcc.c-torture/compile/20000211-1.c b/gcc/testsuite/gcc.c-torture/compile/20000211-1.c index 7a7c8c0cb20..b83d6a40520 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000211-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000211-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef __SIZE_TYPE__ size_t; typedef unsigned char Bufbyte; typedef int Bytecount; diff --git a/gcc/testsuite/gcc.c-torture/compile/20000403-1.c b/gcc/testsuite/gcc.c-torture/compile/20000403-1.c index 27345b56fef..cb56028fb8b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000403-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000403-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + struct utsname { char sysname[32 ]; char version[32 ]; diff --git a/gcc/testsuite/gcc.c-torture/compile/20000804-1.c b/gcc/testsuite/gcc.c-torture/compile/20000804-1.c index 550669b53a3..95bb0fafd70 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000804-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000804-1.c @@ -5,6 +5,7 @@ /* { dg-skip-if "No 64-bit registers" { m32c-*-* } } */ /* { dg-skip-if "Not enough 64-bit registers" { pdp11-*-* } { "-O0" } { "" } } */ /* { dg-xfail-if "Inconsistent constraint on asm" { csky-*-* } { "-O0" } { "" } } */ +/* { dg-xfail-if "Inconsistent constraint on asm" { bpf-*-* } { "-O0" } { "" } } */ /* { dg-xfail-if "" { h8300-*-* } } */ /* { dg-require-stack-size "99*4+16" } */ diff --git a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c index 073ac6a784d..234cdbf1b14 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c @@ -2,6 +2,7 @@ /* { dg-skip-if "too much code for avr" { "avr-*-*" } } */ /* { dg-skip-if "too much code for pdp11" { "pdp11-*-*" } } */ /* { dg-skip-if "" { m32c-*-* } } */ +/* { dg-skip-if "jumps too far for eBPF" { bpf-*-* } } */ /* { dg-timeout-factor 4.0 } */ /* This testcase exposed two branch shortening bugs on powerpc. */ diff --git a/gcc/testsuite/gcc.c-torture/compile/20030903-1.c b/gcc/testsuite/gcc.c-torture/compile/20030903-1.c index fa4d30db6c0..116b0923721 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20030903-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20030903-1.c @@ -1,6 +1,8 @@ /* Derived from PR optimization/11700. */ /* The compiler used to ICE during reload for m68k targets. */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + void check_complex (__complex__ double, __complex__ double, __complex__ double, __complex__ int); void check_float (double, double, double, int); diff --git a/gcc/testsuite/gcc.c-torture/compile/20031125-1.c b/gcc/testsuite/gcc.c-torture/compile/20031125-1.c index d3e92679c8b..bec6c9372a8 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20031125-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20031125-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + short *_offsetTable; /* This tests to make sure PRE splits the entry block ->block 0 edge when there are multiple block 0 predecessors. diff --git a/gcc/testsuite/gcc.c-torture/compile/20040101-1.c b/gcc/testsuite/gcc.c-torture/compile/20040101-1.c index 5c2688ad830..6027cb53fb4 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20040101-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20040101-1.c @@ -1,4 +1,5 @@ /* { dg-skip-if "not enough registers" { pdp11-*-* } } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef unsigned short uint16_t; typedef unsigned int uint32_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/20040317-2.c b/gcc/testsuite/gcc.c-torture/compile/20040317-2.c index 3c8ee2b8ec5..3a1fbde2969 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20040317-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/20040317-2.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef struct _ScaleRec *ScaleWidget; typedef struct { diff --git a/gcc/testsuite/gcc.c-torture/compile/20040726-1.c b/gcc/testsuite/gcc.c-torture/compile/20040726-1.c index e53ccd655bb..aea43a56f34 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20040726-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20040726-1.c @@ -1,4 +1,6 @@ /* PR rtl-optimization/16643 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + void foo (int a, int b, int c, int d, int e, int *f) { if (a == 0) diff --git a/gcc/testsuite/gcc.c-torture/compile/20051216-1.c b/gcc/testsuite/gcc.c-torture/compile/20051216-1.c index ed6ac723069..55751ec8ab2 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20051216-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20051216-1.c @@ -1,4 +1,5 @@ /* PR rtl-optimization/25432 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ void *malloc (__SIZE_TYPE__); void *realloc (void *, __SIZE_TYPE__); diff --git a/gcc/testsuite/gcc.c-torture/compile/20101217-1.c b/gcc/testsuite/gcc.c-torture/compile/20101217-1.c index c4eef0ed464..46bdcf5e347 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20101217-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20101217-1.c @@ -1,5 +1,7 @@ /* Testcase provided by HUAWEI. */ -#include + +extern int printf (const char * __format, ...); + int main() { int cur_k; diff --git a/gcc/testsuite/gcc.c-torture/compile/900313-1.c b/gcc/testsuite/gcc.c-torture/compile/900313-1.c index 2bac5814a7b..12252b4b229 100644 --- a/gcc/testsuite/gcc.c-torture/compile/900313-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/900313-1.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target alloca } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + main () { char *a; diff --git a/gcc/testsuite/gcc.c-torture/compile/920501-7.c b/gcc/testsuite/gcc.c-torture/compile/920501-7.c index 2af15e3b7ec..0fac5f3495f 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920501-7.c +++ b/gcc/testsuite/gcc.c-torture/compile/920501-7.c @@ -1,3 +1,4 @@ /* { dg-require-effective-target label_values } */ +/* { dg-skip-if "no support for indirect jumps" { bpf-*-* } } */ x(){if(&&e-&&b<0)x();b:goto*&&b;e:;} diff --git a/gcc/testsuite/gcc.c-torture/compile/920625-1.c b/gcc/testsuite/gcc.c-torture/compile/920625-1.c index 720d43fd42f..759a356b5b7 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920625-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/920625-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef unsigned long int unsigned_word; typedef signed long int signed_word; typedef unsigned_word word; diff --git a/gcc/testsuite/gcc.c-torture/compile/930421-1.c b/gcc/testsuite/gcc.c-torture/compile/930421-1.c index 01b465f7fec..9e16fe17dd9 100644 --- a/gcc/testsuite/gcc.c-torture/compile/930421-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/930421-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + double q(double); f (int **x, int *r, int *s, int a, int b, int c, int d) diff --git a/gcc/testsuite/gcc.c-torture/compile/930623-1.c b/gcc/testsuite/gcc.c-torture/compile/930623-1.c index 022ad01804e..dd45bbccc38 100644 --- a/gcc/testsuite/gcc.c-torture/compile/930623-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/930623-1.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "no __builtin_apply in eBPF" { bpf-*-* } } */ g (a, b) {} diff --git a/gcc/testsuite/gcc.c-torture/compile/961004-1.c b/gcc/testsuite/gcc.c-torture/compile/961004-1.c index 6407b625d66..cf47f60d5ea 100644 --- a/gcc/testsuite/gcc.c-torture/compile/961004-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/961004-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + void f1 (o1, o2, o3, i, j, k) long long *o1, *o2, *o3; diff --git a/gcc/testsuite/gcc.c-torture/compile/980504-1.c b/gcc/testsuite/gcc.c-torture/compile/980504-1.c index 7b757ccd2e8..6e043a7af19 100644 --- a/gcc/testsuite/gcc.c-torture/compile/980504-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/980504-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef struct _geom_elem { double coeffs[6]; } pGeomDefRec, *pGeomDefPtr; diff --git a/gcc/testsuite/gcc.c-torture/compile/980816-1.c b/gcc/testsuite/gcc.c-torture/compile/980816-1.c index a79100fab57..5bd83b17063 100644 --- a/gcc/testsuite/gcc.c-torture/compile/980816-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/980816-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef __SIZE_TYPE__ size_t; typedef void *XtPointer; diff --git a/gcc/testsuite/gcc.c-torture/compile/990625-1.c b/gcc/testsuite/gcc.c-torture/compile/990625-1.c index 97a2331c7a5..befff06579e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/990625-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/990625-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "no string.h in eBPF" { bpf-*-* } } */ + #define __USE_STRING_INLINES #include diff --git a/gcc/testsuite/gcc.c-torture/compile/DFcmp.c b/gcc/testsuite/gcc.c-torture/compile/DFcmp.c index 3bb253476d7..808874de1a8 100644 --- a/gcc/testsuite/gcc.c-torture/compile/DFcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/DFcmp.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target int32plus } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type double type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/HIcmp.c b/gcc/testsuite/gcc.c-torture/compile/HIcmp.c index 77b47886ed1..6e68271a009 100644 --- a/gcc/testsuite/gcc.c-torture/compile/HIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/HIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type short type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/HIset.c b/gcc/testsuite/gcc.c-torture/compile/HIset.c index 163cb7cbe32..a0d426c2c07 100644 --- a/gcc/testsuite/gcc.c-torture/compile/HIset.c +++ b/gcc/testsuite/gcc.c-torture/compile/HIset.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define E0 ((type *)10000000) #define reg0 r0 #define indreg0 (*p0) diff --git a/gcc/testsuite/gcc.c-torture/compile/QIcmp.c b/gcc/testsuite/gcc.c-torture/compile/QIcmp.c index c5161646f2c..a4dba2487e4 100644 --- a/gcc/testsuite/gcc.c-torture/compile/QIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/QIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type signed char type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/QIset.c b/gcc/testsuite/gcc.c-torture/compile/QIset.c index 212609dc864..e2fde2bda7e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/QIset.c +++ b/gcc/testsuite/gcc.c-torture/compile/QIset.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define E0 ((type *)10000000) #define reg0 r0 #define indreg0 (*p0) diff --git a/gcc/testsuite/gcc.c-torture/compile/SFset.c b/gcc/testsuite/gcc.c-torture/compile/SFset.c index dc7f48dd2dd..a7efecf9717 100644 --- a/gcc/testsuite/gcc.c-torture/compile/SFset.c +++ b/gcc/testsuite/gcc.c-torture/compile/SFset.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target int32plus } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ #define E0 ((type *)10000000) #define reg0 r0 diff --git a/gcc/testsuite/gcc.c-torture/compile/SIcmp.c b/gcc/testsuite/gcc.c-torture/compile/SIcmp.c index 4a9e0d57fd7..ce1281b6093 100644 --- a/gcc/testsuite/gcc.c-torture/compile/SIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/SIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type int type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/SIset.c b/gcc/testsuite/gcc.c-torture/compile/SIset.c index 5fb93579f4b..b200a264b95 100644 --- a/gcc/testsuite/gcc.c-torture/compile/SIset.c +++ b/gcc/testsuite/gcc.c-torture/compile/SIset.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define E0 ((type *)10000000) #define reg0 r0 #define indreg0 (*p0) diff --git a/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c b/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c index 529e3a33fd3..b0029d23ea4 100644 --- a/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type unsigned short type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c b/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c index 3e9cdebc903..e28d13b03ab 100644 --- a/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type unsigned char type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/USIcmp.c b/gcc/testsuite/gcc.c-torture/compile/USIcmp.c index 69788a45b2e..27e5503bd4d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/USIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/USIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type unsigned int type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/consec.c b/gcc/testsuite/gcc.c-torture/compile/consec.c index 01fa25b009b..b8c376d7076 100644 --- a/gcc/testsuite/gcc.c-torture/compile/consec.c +++ b/gcc/testsuite/gcc.c-torture/compile/consec.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + int glob; conseq (a, b, c, d) diff --git a/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c b/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c index 0bd8f6af995..53204735493 100644 --- a/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c +++ b/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c @@ -1,5 +1,6 @@ /* { dg-skip-if "too complex for avr" { avr-*-* } } */ /* { dg-skip-if "ptxas times out" { nvptx-*-* } } */ +/* { dg-skip-if "no chance for bpf" { bpf-*-* } } */ /* { dg-timeout-factor 4.0 } */ #define LIM1(x) x##0, x##1, x##2, x##3, x##4, x##5, x##6, x##7, x##8, x##9, #define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \ diff --git a/gcc/testsuite/gcc.c-torture/compile/lll.c b/gcc/testsuite/gcc.c-torture/compile/lll.c index dee9dc37d15..ea09c871c6b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/lll.c +++ b/gcc/testsuite/gcc.c-torture/compile/lll.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ byte_match_count2 (buf, n, xm, m1, m2, m3, m4) unsigned *buf; diff --git a/gcc/testsuite/gcc.c-torture/compile/parms.c b/gcc/testsuite/gcc.c-torture/compile/parms.c index 8205a9c1454..1bfc93d2abb 100644 --- a/gcc/testsuite/gcc.c-torture/compile/parms.c +++ b/gcc/testsuite/gcc.c-torture/compile/parms.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target alloca } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ #define alloca __builtin_alloca x (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, x, y) diff --git a/gcc/testsuite/gcc.c-torture/compile/pass.c b/gcc/testsuite/gcc.c-torture/compile/pass.c index 4e028393feb..529a01dac85 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pass.c +++ b/gcc/testsuite/gcc.c-torture/compile/pass.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + int foo (a, b, c) { diff --git a/gcc/testsuite/gcc.c-torture/compile/poor.c b/gcc/testsuite/gcc.c-torture/compile/poor.c index 66d584aff43..20287ef2354 100644 --- a/gcc/testsuite/gcc.c-torture/compile/poor.c +++ b/gcc/testsuite/gcc.c-torture/compile/poor.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + typedef struct { char c[510]; diff --git a/gcc/testsuite/gcc.c-torture/compile/pp.c b/gcc/testsuite/gcc.c-torture/compile/pp.c index 7d38d53de0f..c1e09eab407 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pp.c +++ b/gcc/testsuite/gcc.c-torture/compile/pp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + foo (a, b, c, d, e, i0, f, i1) double a, b, c, d, e, f; int i0, i1; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr25311.c b/gcc/testsuite/gcc.c-torture/compile/pr25311.c index 26c5bc37b83..43ef3fd9523 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr25311.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr25311.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ struct w { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr32399.c b/gcc/testsuite/gcc.c-torture/compile/pr32399.c index cc2b1b18984..b29dbd7986a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr32399.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr32399.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + void f(unsigned char *src, unsigned char *dst, int num, unsigned char *pos, unsigned char *diffuse, int hasdiffuse, unsigned char *specular, int hasspecular) { int i; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34091.c b/gcc/testsuite/gcc.c-torture/compile/pr34091.c index 0b8549132e6..a623a383fd0 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr34091.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr34091.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef unsigned int GLenum; typedef unsigned char GLboolean; typedef int GLint; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34688.c b/gcc/testsuite/gcc.c-torture/compile/pr34688.c index 60e0f3c9f15..ec890cb8f15 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr34688.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr34688.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef __SIZE_TYPE__ size_t; typedef struct { } diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37258.c b/gcc/testsuite/gcc.c-torture/compile/pr37258.c index 286f2fc4427..41801781e3a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37258.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37258.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37327.c b/gcc/testsuite/gcc.c-torture/compile/pr37327.c index 79946b7522d..5ca9d1d45b6 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37327.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37327.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37381.c b/gcc/testsuite/gcc.c-torture/compile/pr37381.c index a2fed66c4ee..d8cd47d329d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37381.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37381.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + extern unsigned int __invalid_size_argument_for_IOC; typedef unsigned int __u32; struct video_window diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c b/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c index abeae7a2f32..2170dda67f0 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c @@ -1,4 +1,5 @@ /* PR middle-end/37669 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ #define FMT10 "%d%d%d%d%d%d%d%d%d%d" #define FMT100 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37669.c b/gcc/testsuite/gcc.c-torture/compile/pr37669.c index a2eafc75cb3..36e4c39d8ed 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37669.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37669.c @@ -1,6 +1,7 @@ /* This testcase used to fail because a miscompiled execute_fold_all_builtins. */ /* { dg-options "-fgnu89-inline" } */ /* { dg-require-effective-target int32plus } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef __SIZE_TYPE__ size_t; extern __inline __attribute__ ((__always_inline__)) int __attribute__ diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c b/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c index 541bd42ad5d..9e7b10fb7a3 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + void matmul_i4 (int * __restrict dest_y, const int * __restrict abase, const int * __restrict bbase_y, diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39928-1.c b/gcc/testsuite/gcc.c-torture/compile/pr39928-1.c index 1abb5ccb505..ae6a63b24b8 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr39928-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr39928-1.c @@ -1,4 +1,6 @@ /* { dg-options "-msse" { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); extern __m128 _mm_sub_ps (__m128 __A, __m128 __B); extern __m128 _mm_mul_ps (__m128 __A, __m128 __B); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr44063.c b/gcc/testsuite/gcc.c-torture/compile/pr44063.c index 596e1dc991f..32208f610f9 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr44063.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr44063.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + typedef signed char int8_t; typedef short int16_t; typedef unsigned char uint8_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr48596.c b/gcc/testsuite/gcc.c-torture/compile/pr48596.c index 382a152413e..743bd82e868 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr48596.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr48596.c @@ -1,4 +1,6 @@ /* PR target/48596 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + enum { nrrdCenterUnknown, nrrdCenterNode, nrrdCenterCell, nrrdCenterLast }; typedef struct { int size; int center; } NrrdAxis; typedef struct { int dim; NrrdAxis axis[10]; } Nrrd; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr51856.c b/gcc/testsuite/gcc.c-torture/compile/pr51856.c index 6644c7fdc14..823a0bed073 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr51856.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr51856.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + struct B { int b1; long long b2, b3; int b4; }; struct C { char c1[40], c2, c3[96]; long long c4[5], c5; char c6[596]; }; void fn1 (long long), fn2 (char *, int), fn4 (void); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54428.c b/gcc/testsuite/gcc.c-torture/compile/pr54428.c index 84a5dbd82bd..d783337cfdb 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr54428.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr54428.c @@ -1,4 +1,5 @@ /* PR c/54428 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef double _Complex C; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c index f042ea2fc6c..0d4172a576b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c @@ -1,4 +1,5 @@ /* PR tree-optimization/54713 */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ #ifndef N #define N 8 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c index c3910373111..f7d2364e197 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c @@ -1,4 +1,5 @@ /* PR tree-optimization/54713 */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ #define N 16 #define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c index 6164a5eec0e..76a35b067c5 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c @@ -1,4 +1,5 @@ /* PR tree-optimization/54713 */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ #define N 32 #define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ diff --git a/gcc/testsuite/gcc.c-torture/compile/pr55921.c b/gcc/testsuite/gcc.c-torture/compile/pr55921.c index de0635d66ad..cf9084e33f0 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr55921.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr55921.c @@ -1,5 +1,6 @@ /* PR tree-optimization/55921 */ /* { dg-skip-if "Not enough registers" { "pdp11-*-*" } } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ typedef union { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70061.c b/gcc/testsuite/gcc.c-torture/compile/pr70061.c index a7ebcfc99f8..aabfddad43f 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr70061.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr70061.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef int v8si __attribute__ ((vector_size (32))); int diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70240.c b/gcc/testsuite/gcc.c-torture/compile/pr70240.c index 830d4ddcc93..466d3a7c961 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr70240.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr70240.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef short v16hi __attribute__ ((vector_size (32))); typedef int v8si __attribute__ ((vector_size (32))); typedef long long v4di __attribute__ ((vector_size (32))); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70355.c b/gcc/testsuite/gcc.c-torture/compile/pr70355.c index 474942715f8..f7114208005 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr70355.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr70355.c @@ -1,5 +1,7 @@ /* { dg-require-effective-target int128 } */ /* { dg-additional-options "-g" } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + typedef unsigned __int128 v2ti __attribute__ ((vector_size (32))); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr82052.c b/gcc/testsuite/gcc.c-torture/compile/pr82052.c index 3763161e350..09fac5edb1e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr82052.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr82052.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned uint32_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr83487.c b/gcc/testsuite/gcc.c-torture/compile/pr83487.c index 9effb1eef03..9de0e17939f 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr83487.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr83487.c @@ -1,4 +1,5 @@ /* PR middle-end/83487 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ struct __attribute__ ((aligned)) A {}; struct A a; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr86122.c b/gcc/testsuite/gcc.c-torture/compile/pr86122.c index 0a4fd144ae6..1bd46733183 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr86122.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr86122.c @@ -1,4 +1,5 @@ /* PR middle-end/86122 */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ _Complex int foo (_Complex int x) diff --git a/gcc/testsuite/gcc.c-torture/compile/pret-arg.c b/gcc/testsuite/gcc.c-torture/compile/pret-arg.c index a7fa8562830..d86d135dc4b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pret-arg.c +++ b/gcc/testsuite/gcc.c-torture/compile/pret-arg.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + foo (a, b, c, d, e, f, g, h, i, j, xx) double xx; { diff --git a/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c b/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c index f5f01116eda..77518866d3f 100644 --- a/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c +++ b/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + int foo; typedef long unsigned int size_t; typedef short unsigned int wchar_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/structret.c b/gcc/testsuite/gcc.c-torture/compile/structret.c index 9c705d4c0a2..d99eaa630bb 100644 --- a/gcc/testsuite/gcc.c-torture/compile/structret.c +++ b/gcc/testsuite/gcc.c-torture/compile/structret.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + struct foo { int a, b, c, d; diff --git a/gcc/testsuite/gcc.c-torture/compile/uuarg.c b/gcc/testsuite/gcc.c-torture/compile/uuarg.c index 930dd8ab5f6..875c7c3b50f 100644 --- a/gcc/testsuite/gcc.c-torture/compile/uuarg.c +++ b/gcc/testsuite/gcc.c-torture/compile/uuarg.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + foo (a, b, c, d, e, f, g, h, i) { return foo () + i; diff --git a/gcc/testsuite/gcc.dg/20001009-1.c b/gcc/testsuite/gcc.dg/20001009-1.c index 1a5567779b5..580e4b4d307 100644 --- a/gcc/testsuite/gcc.dg/20001009-1.c +++ b/gcc/testsuite/gcc.dg/20001009-1.c @@ -1,5 +1,6 @@ /* { dg-do compile { target fpic } } */ /* { dg-options "-O2 -fpic" } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ extern void foo (void *a, double x, double y); void diff --git a/gcc/testsuite/gcc.dg/20020418-1.c b/gcc/testsuite/gcc.dg/20020418-1.c index 7314ec000ef..456967fdd36 100644 --- a/gcc/testsuite/gcc.dg/20020418-1.c +++ b/gcc/testsuite/gcc.dg/20020418-1.c @@ -2,6 +2,7 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ /* { dg-options "-O2 -msse -ffast-math" { target i?86-*-* x86_64-*-* } } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ void bar (float *a, float *b); diff --git a/gcc/testsuite/gcc.dg/20020426-2.c b/gcc/testsuite/gcc.dg/20020426-2.c index 9ad7a54f601..96517f7b840 100644 --- a/gcc/testsuite/gcc.dg/20020426-2.c +++ b/gcc/testsuite/gcc.dg/20020426-2.c @@ -3,6 +3,7 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ /* { dg-options "-O2 -frename-registers -fomit-frame-pointer -fPIC -mtune=i686" { target { { i?86-*-* x86_64-*-* } && { ia32 && fpic } } } } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/20020430-1.c b/gcc/testsuite/gcc.dg/20020430-1.c index 63915a24b17..f48bb672aaf 100644 --- a/gcc/testsuite/gcc.dg/20020430-1.c +++ b/gcc/testsuite/gcc.dg/20020430-1.c @@ -6,6 +6,7 @@ /* { dg-do compile { target fpic } } */ /* { dg-options "-O2 -frename-registers -fpic" } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef unsigned long XID; typedef XID Window; diff --git a/gcc/testsuite/gcc.dg/20040306-1.c b/gcc/testsuite/gcc.dg/20040306-1.c index 903d20ac256..8cac8697d99 100644 --- a/gcc/testsuite/gcc.dg/20040306-1.c +++ b/gcc/testsuite/gcc.dg/20040306-1.c @@ -2,7 +2,7 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ - +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef struct test { diff --git a/gcc/testsuite/gcc.dg/20040622-2.c b/gcc/testsuite/gcc.dg/20040622-2.c index 0be320fa4e2..e62ec36d43a 100644 --- a/gcc/testsuite/gcc.dg/20040622-2.c +++ b/gcc/testsuite/gcc.dg/20040622-2.c @@ -1,5 +1,6 @@ /* { dg-do link } */ /* { dg-require-effective-target ptr32plus } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ /* This validates codegen for [r1+32760] on Darwin. */ void f(char x[32688], double *y, double *z) __attribute__((noinline)); void f(char x[32688], double *y, double *z) {} diff --git a/gcc/testsuite/gcc.dg/20050603-2.c b/gcc/testsuite/gcc.dg/20050603-2.c index 8c8e58e1b4d..a135e3ea1a0 100644 --- a/gcc/testsuite/gcc.dg/20050603-2.c +++ b/gcc/testsuite/gcc.dg/20050603-2.c @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ +/* { dg-skip-if "no stdlib.h in eBPF" { bpf-*-* } } */ #include struct s { unsigned short f: 16; diff --git a/gcc/testsuite/gcc.dg/20050629-1.c b/gcc/testsuite/gcc.dg/20050629-1.c index 0dd47f7024b..99d9ce823b0 100644 --- a/gcc/testsuite/gcc.dg/20050629-1.c +++ b/gcc/testsuite/gcc.dg/20050629-1.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -w" } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ /* This file was automatically reduced from tree-ssa-operands.c. It contains many warnings, but it exposes a copy propagation bug that diff --git a/gcc/testsuite/gcc.dg/20061026.c b/gcc/testsuite/gcc.dg/20061026.c index 741ea2eb3b8..fa8069ce4cf 100644 --- a/gcc/testsuite/gcc.dg/20061026.c +++ b/gcc/testsuite/gcc.dg/20061026.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O1" } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ /* This testcase failed on s390. The frame size for function f will be exactly 32768 bytes. The back end has to recognize that this is to diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-3.c index 773f4633dc7..f119502f025 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-3.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-3.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -Warray-bounds" } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ /* based on PR 31227 */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-30.c b/gcc/testsuite/gcc.dg/Warray-bounds-30.c index ac7e9a6e8fb..b9965682101 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-30.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-30.c @@ -1,7 +1,8 @@ /* PR tree-optimization/84047 - missing -Warray-bounds on an out-of-bounds index into an array { dg-do compile } - { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" } */ + { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" } + { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ #include "range.h" diff --git a/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c b/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c index 1a5402f8120..d7068d04aef 100644 --- a/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c +++ b/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c @@ -1,6 +1,7 @@ /* Exercise -Wframe-larger-than= with a byte-size suffix. { dg-do compile } - { dg-options "-O -Wframe-larger-than=1KB" } */ + { dg-options "-O -Wframe-larger-than=1KB" } + { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ extern void f (void*, ...); diff --git a/gcc/testsuite/gcc.dg/Wframe-larger-than.c b/gcc/testsuite/gcc.dg/Wframe-larger-than.c index fab0adf37ee..8a40cf36df8 100644 --- a/gcc/testsuite/gcc.dg/Wframe-larger-than.c +++ b/gcc/testsuite/gcc.dg/Wframe-larger-than.c @@ -4,6 +4,7 @@ /* { dg-do compile } */ /* { dg-options "-Wframe-larger-than=2048" } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ extern void func(char *); diff --git a/gcc/testsuite/gcc.dg/Wrestrict-11.c b/gcc/testsuite/gcc.dg/Wrestrict-11.c index 7b4b5aa2527..07b9cddad4b 100644 --- a/gcc/testsuite/gcc.dg/Wrestrict-11.c +++ b/gcc/testsuite/gcc.dg/Wrestrict-11.c @@ -3,7 +3,8 @@ that calls to strncpy involving multidimensional arrays of structs don't trigger false positive -Wrestrict warnings. { dg-do compile } - { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } */ + { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } + { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/builtins-config.h b/gcc/testsuite/gcc.dg/builtins-config.h index f00e91a750f..5e27c1deb33 100644 --- a/gcc/testsuite/gcc.dg/builtins-config.h +++ b/gcc/testsuite/gcc.dg/builtins-config.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2009, 2011, 2012 +/* Copyright (C) 2003, 2004, 2005, 2006, 2009, 2011, 2012, 2019 Free Software Foundation. Define macros useful in tests for bulitin functions. */ @@ -20,6 +20,8 @@ /* FreeBSD up to version 8 lacks support for cexp and friends. */ #elif defined(__vxworks) /* VxWorks doesn't have a full C99 time. (cabs is missing, for example.) */ +#elif defined (__BPF__) +/* No chance for eBPF to support C99 functions. */ #elif defined(_WIN32) && !defined(__CYGWIN__) /* Windows doesn't have the entire C99 runtime. */ #elif (defined(__APPLE__) && defined(__ppc__) \ diff --git a/gcc/testsuite/gcc.target/bpf/bpf.exp b/gcc/testsuite/gcc.target/bpf/bpf.exp new file mode 100644 index 00000000000..e5c8cfcf6b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/bpf.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2019 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an eBPF target. +if ![istarget bpf-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.target/bpf/builtin-load.c b/gcc/testsuite/gcc.target/bpf/builtin-load.c new file mode 100644 index 00000000000..0f93d91fb6f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/builtin-load.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -std=gnu99" } */ + +void foo () +{ + long long ll, off; + + /* Indirect. */ + ll = __builtin_bpf_load_byte (off); + ll = __builtin_bpf_load_half (off); + ll = __builtin_bpf_load_word (off); + + /* Absolute. */ + ll = __builtin_bpf_load_byte (0); + ll = __builtin_bpf_load_half (4); + ll = __builtin_bpf_load_word (8); +} + +/* { dg-final { scan-assembler "ldindb\t%r.,0.*ldindh\t%r.,0.*ldindw\t%r.,0" } } */ +/* { dg-final { scan-assembler "ldabsb\t0.*ldabsh\t4.*ldabsw\t8" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/constant-calls.c b/gcc/testsuite/gcc.target/bpf/constant-calls.c new file mode 100644 index 00000000000..84612a92ae9 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/constant-calls.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-xfail-if "" { bpf-*-* } } */ + +typedef void *(*T)(void); +f1 () +{ + ((T) 0)(); +} +f2 () +{ + ((T) 1000)(); +} +f3 () +{ + ((T) 1000000)(); +} + +/* { dg-final { scan-assembler "call\t0" } } */ +/* { dg-final { scan-assembler "call\t1000" } } */ +/* { dg-final { scan-assembler "call\t10000" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c new file mode 100644 index 00000000000..7c991af336b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c @@ -0,0 +1,26 @@ +/* Verify proper errors are generated for functions taking too many + arguments, with aggregates and 128-bit arguments. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +#include + +struct ja +{ + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; +}; + +void jorl (struct ja, unsigned __int128, unsigned __int128, int i3); + +int foo () +{ + struct ja je; + jorl (je, 1, 2, 3); /* { dg-error "too many function arguments" } */ + return 2L /1; +} + diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c new file mode 100644 index 00000000000..d9d42c18258 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c @@ -0,0 +1,26 @@ +/* Verify proper errors are generated for functions taking too many + arguments, with aggregates and 128-bit arguments. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +#include + +struct ja +{ + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; +}; + +void jorl (struct ja, int, int, int, unsigned __int128); + +int foo () +{ + struct ja je; + jorl (je, 1, 2, 3, 4); /* { dg-error "too many function arguments" } */ + return 2L /1; +} + diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs.c b/gcc/testsuite/gcc.target/bpf/diag-funargs.c new file mode 100644 index 00000000000..d4e9c0683f2 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-funargs.c @@ -0,0 +1,15 @@ +/* Verify proper errors are generated for functions taking too many + arguments. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +int +foo (int a1, /* { dg-error "too many function arguments" } */ + int a2, + int a3, + int a4, + int a5, + int a6) +{ + return a6; +} diff --git a/gcc/testsuite/gcc.target/bpf/diag-indcalls.c b/gcc/testsuite/gcc.target/bpf/diag-indcalls.c new file mode 100644 index 00000000000..9263fcf7e1a --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-indcalls.c @@ -0,0 +1,11 @@ +/* Verify proper errors are generated for indirect function calls. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +void (*fnp) (void); + +void +foo () +{ + (*fnp) (); +} /* { dg-error "indirect call in function" } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-bind.c b/gcc/testsuite/gcc.target/bpf/helper-bind.c new file mode 100644 index 00000000000..2d1fedc4ce8 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-bind.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *addr; + int addr_len; + + ret = __builtin_bpf_helper_bind (ctx, addr, addr_len); +} + +/* { dg-final { scan-assembler "call\t64" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c b/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c new file mode 100644 index 00000000000..844c88d3e34 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + uint32_t ifindex; + uint64_t flags; + + ret = __builtin_bpf_helper_redirect (ifindex, flags); +} + +/* { dg-final { scan-assembler "call\t23" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c b/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c new file mode 100644 index 00000000000..a4fb8139234 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t ifindex; + uint64_t flags; + + ret = __builtin_bpf_helper_clone_redirect (skb, ifindex, flags); +} + +/* { dg-final { scan-assembler "call\t13" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c b/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c new file mode 100644 index 00000000000..ef38192efd3 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int64_t ret; + int32_t *to, *from; + uint64_t to_size, from_size; + int seed; + + ret = __builtin_bpf_helper_csum_diff (from, from_size, to, to_size, seed); +} + +/* { dg-final { scan-assembler "call\t28" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-csum-update.c b/gcc/testsuite/gcc.target/bpf/helper-csum-update.c new file mode 100644 index 00000000000..3cde8678cb5 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-csum-update.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int64_t ret; + void *skb; + int csum; + + ret = __builtin_bpf_helper_csum_update (skb, csum); +} + +/* { dg-final { scan-assembler "call\t40" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c b/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c new file mode 100644 index 00000000000..a7eb6e617e8 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *map; + uint32_t index; + + ret = __builtin_bpf_helper_current_task_under_cgroup (map, index); +} + +/* { dg-final { scan-assembler "call\t37" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c b/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c new file mode 100644 index 00000000000..9a9f79d402c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *params; + int plen; + uint32_t flags; + + ret = __builtin_bpf_helper_fib_lookup (ctx, params, plen, flags); +} + +/* { dg-final { scan-assembler "call\t69" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c b/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c new file mode 100644 index 00000000000..6cfd14d0ad1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_cgroup_classid (skb); +} + +/* { dg-final { scan-assembler "call\t17" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c new file mode 100644 index 00000000000..916dc4d3bb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + + ret = __builtin_bpf_helper_get_current_cgroup_id (); +} + +/* { dg-final { scan-assembler "call\t80" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c new file mode 100644 index 00000000000..efc330c3c98 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *buf; + uint32_t size_of_buf; + + ret = __builtin_bpf_helper_get_current_comm (buf, size_of_buf); +} + +/* { dg-final { scan-assembler "call\t16" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c new file mode 100644 index 00000000000..32d3e9c91d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + + ret = __builtin_bpf_helper_get_current_pid_tgid (); +} + +/* { dg-final { scan-assembler "call\t14" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c new file mode 100644 index 00000000000..016c134b132 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + + ret = __builtin_bpf_helper_get_current_task (); +} + +/* { dg-final { scan-assembler "call\t35" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c new file mode 100644 index 00000000000..1dc2f9f41e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + + ret = __builtin_bpf_helper_get_current_uid_gid (); +} + +/* { dg-final { scan-assembler "call\t15" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c b/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c new file mode 100644 index 00000000000..1db5d871c26 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_hash_recalc (skb); +} + +/* { dg-final { scan-assembler "call\t34" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c b/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c new file mode 100644 index 00000000000..298da1c949b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret, *sk; + + ret = __builtin_bpf_helper_get_listener_sock (sk); +} + +/* { dg-final { scan-assembler "call\t98" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c b/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c new file mode 100644 index 00000000000..88da67e99ae --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret, *map; + uint64_t flags; + + ret = __builtin_bpf_helper_get_local_storage (map, flags); +} + +/* { dg-final { scan-assembler "call\t81" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c new file mode 100644 index 00000000000..628e1012152 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + + ret = __builtin_bpf_helper_get_numa_node_id (); +} + +/* { dg-final { scan-assembler "call\t42" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c b/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c new file mode 100644 index 00000000000..6d3e5bc7a22 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + + ret = __builtin_bpf_helper_get_prandom_u32 (); +} + +/* { dg-final { scan-assembler "call\t7" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c b/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c new file mode 100644 index 00000000000..5056c4adb1f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_route_realm (skb); +} + +/* { dg-final { scan-assembler "call\t24" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c new file mode 100644 index 00000000000..655b87341df --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + + ret = __builtin_bpf_helper_get_smp_processor_id (); +} + +/* { dg-final { scan-assembler "call\t8" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c b/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c new file mode 100644 index 00000000000..afd17ddcd50 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_socket_cookie (skb); +} + +/* { dg-final { scan-assembler "call\t46" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c b/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c new file mode 100644 index 00000000000..3a274c965f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_socket_uid (skb); +} + +/* { dg-final { scan-assembler "call\t47" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-stack.c b/gcc/testsuite/gcc.target/bpf/helper-get-stack.c new file mode 100644 index 00000000000..bbcdeb58775 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-stack.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *regs, *buf; + uint32_t size; + uint64_t flags; + + ret = __builtin_bpf_helper_get_stack (regs, buf, size, flags); +} + +/* { dg-final { scan-assembler "call\t67" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c b/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c new file mode 100644 index 00000000000..319d15cd2fa --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *map; + uint64_t flags; + + ret = __builtin_bpf_helper_get_stackid (ctx, map, flags); +} + +/* { dg-final { scan-assembler "call\t27" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c b/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c new file mode 100644 index 00000000000..fb16f15e6ea --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *bpf_socket; + int level, optname, optlen; + char *optval; + + ret = __builtin_bpf_helper_getsockopt (bpf_socket, level, + optname, optval, optlen); +} + +/* { dg-final { scan-assembler "call\t57" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c b/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c new file mode 100644 index 00000000000..405df057e30 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + ret = __builtin_bpf_helper_ktime_get_ns (); +} + +/* { dg-final { scan-assembler "call\t5" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c b/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c new file mode 100644 index 00000000000..ac17662c5d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t offset; + uint64_t from, to, size; + + ret = __builtin_bpf_helper_l3_csum_replace (skb, offset, from, to, size); +} + +/* { dg-final { scan-assembler "call\t10" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c b/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c new file mode 100644 index 00000000000..52b5514b6cb --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t offset; + uint64_t from, to, size; + + ret = __builtin_bpf_helper_l4_csum_replace (skb, offset, from, to, size); +} + +/* { dg-final { scan-assembler "call\t11" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c new file mode 100644 index 00000000000..1baed27fac7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *hdr; + uint32_t type, len; + + ret = __builtin_bpf_helper_lwt_push_encap (skb, type, hdr, len); +} + +/* { dg-final { scan-assembler "call\t73" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c new file mode 100644 index 00000000000..ccc94c1af9d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *param; + uint32_t action, param_len; + + ret = __builtin_bpf_helper_lwt_seg6_action (skb, action, + param, param_len); +} + +/* { dg-final { scan-assembler "call\t76" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c new file mode 100644 index 00000000000..5e95124ad0f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t offset, delta; + + ret = __builtin_bpf_helper_lwt_seg6_adjust_srh (skb, offset, + delta); +} + +/* { dg-final { scan-assembler "call\t75" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c new file mode 100644 index 00000000000..098f97680f2 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *from; + uint32_t offset, len; + + ret = __builtin_bpf_helper_lwt_seg6_store_bytes (skb, offset, + from, len); +} + +/* { dg-final { scan-assembler "call\t74" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c new file mode 100644 index 00000000000..b8a6cdec4ee --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + char *key = 0; + + ret = __builtin_bpf_helper_map_delete_elem (map (), key); +} + +/* { dg-final { scan-assembler "call\t3" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c new file mode 100644 index 00000000000..839cfc423a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + char *key = 0, *value = 0; + value = __builtin_bpf_helper_map_lookup_elem (map (), key); +} + +/* { dg-final { scan-assembler "call\t1" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c new file mode 100644 index 00000000000..6d0acb1dcb7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + char *value = 0; + + ret = __builtin_bpf_helper_map_peek_elem (map (), value); +} + +/* { dg-final { scan-assembler "call\t89" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c new file mode 100644 index 00000000000..71a7851ca9c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + char *value = 0; + + ret = __builtin_bpf_helper_map_pop_elem (map (), value); +} + +/* { dg-final { scan-assembler "call\t88" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c new file mode 100644 index 00000000000..53bc0ac5dd7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + char *value = 0; + long long flags = 0; + + ret = __builtin_bpf_helper_map_push_elem (map (), value, flags); +} + +/* { dg-final { scan-assembler "call\t87" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c new file mode 100644 index 00000000000..6281442ba3d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + long long flags = 0; + char *key = 0, *value = 0; + + ret = __builtin_bpf_helper_map_update_elem (map (), key, value, flags); +} + +/* { dg-final { scan-assembler "call\t2" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c new file mode 100644 index 00000000000..3b831acad64 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg; + uint32_t bytes; + + ret = __builtin_bpf_helper_msg_apply_bytes (msg, bytes); +} + +/* { dg-final { scan-assembler "call\t61" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c new file mode 100644 index 00000000000..2c4ee218832 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg; + uint32_t bytes; + + ret = __builtin_bpf_helper_msg_cork_bytes (msg, bytes); +} + +/* { dg-final { scan-assembler "call\t62" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c new file mode 100644 index 00000000000..377c036603e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t start, pop; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_pop_data (skb, start, pop, flags); +} + +/* { dg-final { scan-assembler "call\t91" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c new file mode 100644 index 00000000000..ef27493122b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg; + uint32_t start, end; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_pull_data (msg, start, end, flags); +} + +/* { dg-final { scan-assembler "call\t63" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c new file mode 100644 index 00000000000..9e256bc5ca7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t start, len; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_push_data (skb, start, len, flags); +} + +/* { dg-final { scan-assembler "call\t90" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c new file mode 100644 index 00000000000..2e9d4137d66 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_redirect_hash (msg, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t71" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c new file mode 100644 index 00000000000..f5f8405e324 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg, *map; + uint64_t key; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_redirect_map (msg, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t60" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-override-return.c b/gcc/testsuite/gcc.target/bpf/helper-override-return.c new file mode 100644 index 00000000000..3bd5424353f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-override-return.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *regs; + uint64_t rc; + + ret = __builtin_bpf_helper_override_return (regs, rc); +} + +/* { dg-final { scan-assembler "call\t58" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c new file mode 100644 index 00000000000..afb32010bdd --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *map; + uint64_t flags; + void *data; + uint64_t size; + + ret = __builtin_bpf_helper_perf_event_output (ctx, map, flags, data, size); +} + +/* { dg-final { scan-assembler "call\t25" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c new file mode 100644 index 00000000000..1d512c9ec65 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *map, *buf; + uint64_t flags; + uint64_t buf_size; + + ret = __builtin_bpf_helper_perf_event_read_value (map, flags, buf, buf_size); +} + +/* { dg-final { scan-assembler "call\t55" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c new file mode 100644 index 00000000000..f099a09d66f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + void *map; + uint64_t flags; + + ret = __builtin_bpf_helper_perf_event_read (map, flags); +} + +/* { dg-final { scan-assembler "call\t22" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c b/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c new file mode 100644 index 00000000000..00c4a3a78b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + uint64_t buf_size; + + ret = __builtin_bpf_helper_perf_prog_read_value (ctx, buf, buf_size); +} + +/* { dg-final { scan-assembler "call\t56" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c b/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c new file mode 100644 index 00000000000..fd04760221d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + int size; + void *dst; + const void *unsafe_ptr; + + ret = __builtin_bpf_helper_probe_read_str (dst, size, unsafe_ptr); +} + +/* { dg-final { scan-assembler "call\t45" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-read.c b/gcc/testsuite/gcc.target/bpf/helper-probe-read.c new file mode 100644 index 00000000000..a77a907767b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-probe-read.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *src, *dst; + uint32_t size; + + ret = __builtin_bpf_helper_probe_read (dst, size, src); +} + +/* { dg-final { scan-assembler "call\t4" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c b/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c new file mode 100644 index 00000000000..bf226206769 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *dst, *src; + uint32_t len; + + ret = __builtin_bpf_helper_probe_write_user (dst, src, len); +} + +/* { dg-final { scan-assembler "call\t36" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c b/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c new file mode 100644 index 00000000000..58e9395dbeb --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx; + uint32_t protocol, toggle; + uint64_t scancode; + + ret = __builtin_bpf_helper_rc_keydown (ctx, protocol, + scancode, toggle); +} + +/* { dg-final { scan-assembler "call\t78" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c b/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c new file mode 100644 index 00000000000..e776bc75963 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx; + int32_t rel_x, rel_y; + + ret = __builtin_bpf_helper_rc_pointer_rel (ctx, rel_x, rel_y); +} + +/* { dg-final { scan-assembler "call\t92" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c b/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c new file mode 100644 index 00000000000..0ebc7de5bdf --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx; + + ret = __builtin_bpf_helper_rc_repeat (ctx); +} + +/* { dg-final { scan-assembler "call\t77" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c new file mode 100644 index 00000000000..daeecc2a01e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *map; + uint32_t key; + uint64_t flags; + + ret = __builtin_bpf_helper_redirect_map (map, key, flags); +} + +/* { dg-final { scan-assembler "call\t51" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c b/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c new file mode 100644 index 00000000000..4bc63ffa063 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *skb; + + __builtin_bpf_helper_set_hash_invalid (skb); +} + +/* { dg-final { scan-assembler "call\t41" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-set-hash.c b/gcc/testsuite/gcc.target/bpf/helper-set-hash.c new file mode 100644 index 00000000000..d01ae6eb268 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-set-hash.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + uint32_t hash; + + ret = __builtin_bpf_helper_set_hash (skb, hash); +} + +/* { dg-final { scan-assembler "call\t48" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c b/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c new file mode 100644 index 00000000000..6f3b450639e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *bpf_socket; + int level; + int optname; + void *optval; + int optlen; + + ret = __builtin_bpf_helper_setsockopt (bpf_socket, level, optname, + optval, optlen); +} + +/* { dg-final { scan-assembler "call\t49" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c b/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c new file mode 100644 index 00000000000..abe813d94f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret, *sk; + + ret = __builtin_bpf_helper_sk_fullsock (sk); +} + +/* { dg-final { scan-assembler "call\t95" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c new file mode 100644 index 00000000000..4408640a6b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret; + void *ctx, *tuple; + uint32_t tuple_size; + uint64_t netns, flags; + + ret = __builtin_bpf_helper_sk_lookup_tcp (ctx, + tuple, + tuple_size, + netns, flags); +} + +/* { dg-final { scan-assembler "call\t84" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c new file mode 100644 index 00000000000..4c50f9c6327 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret; + void *ctx, *tuple; + uint32_t tuple_size; + uint64_t netns, flags; + + ret = __builtin_bpf_helper_sk_lookup_udp (ctx, + tuple, + tuple_size, + netns, flags); +} + +/* { dg-final { scan-assembler "call\t85" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c new file mode 100644 index 00000000000..7047c9f1290 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_sk_redirect_hash (skb, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t72" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c new file mode 100644 index 00000000000..5afb0ac4100 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *map; + uint32_t key; + uint64_t flags; + + ret = __builtin_bpf_helper_sk_redirect_map (ctx, map, key, flags); +} + +/* { dg-final { scan-assembler "call\t52" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-release.c b/gcc/testsuite/gcc.target/bpf/helper-sk-release.c new file mode 100644 index 00000000000..f054c90652c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-release.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *sock; + + ret = __builtin_bpf_helper_sk_release (sock); +} + +/* { dg-final { scan-assembler "call\t86" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c b/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c new file mode 100644 index 00000000000..399ad2c0231 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *reuse, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_sk_select_reuseport (reuse, map, + key, flags); +} + +/* { dg-final { scan-assembler "call\t82" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c new file mode 100644 index 00000000000..07c5875d930 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *map, *sk; + + ret = __builtin_bpf_helper_sk_storage_delete (map, sk); +} + +/* { dg-final { scan-assembler "call\t108" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c new file mode 100644 index 00000000000..a199ef0ae64 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret; + void *map, *sk, *value; + uint64_t flags; + + ret = __builtin_bpf_helper_sk_storage_get (map, sk, value, + flags); +} + +/* { dg-final { scan-assembler "call\t107" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c b/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c new file mode 100644 index 00000000000..88196f5e070 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + int32_t len_diff; + uint32_t mode; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_adjust_room (skb, len_diff, mode, flags); +} + +/* { dg-final { scan-assembler "call\t50" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c new file mode 100644 index 00000000000..7c9021e1763 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + void *skb; + + ret = __builtin_bpf_helper_skb_cgroup_id (skb); +} + +/* { dg-final { scan-assembler "call\t79" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c new file mode 100644 index 00000000000..de6281539fd --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t len; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_change_head (skb, len, flags); +} + +/* { dg-final { scan-assembler "call\t43" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c new file mode 100644 index 00000000000..5738f3cc59b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + int16_t proto; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_change_proto (skb, proto, flags); +} + +/* { dg-final { scan-assembler "call\t31" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c new file mode 100644 index 00000000000..1fb6b45cd1b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t len; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_change_tail (skb, len, flags); +} + +/* { dg-final { scan-assembler "call\t38" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c new file mode 100644 index 00000000000..bcf22cebc28 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t type; + + ret = __builtin_bpf_helper_skb_change_type (skb, type); +} + +/* { dg-final { scan-assembler "call\t32" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c b/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c new file mode 100644 index 00000000000..f769993f120 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + + ret = __builtin_bpf_helper_skb_ecn_set_ce (skb); +} + +/* { dg-final { scan-assembler "call\t97" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c new file mode 100644 index 00000000000..0d4db236865 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *key; + uint32_t size; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_get_tunnel_key (skb, key, size, flags); +} + +/* { dg-final { scan-assembler "call\t20" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c new file mode 100644 index 00000000000..9428657b932 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint8_t *opt; + uint32_t size; + + ret = __builtin_bpf_helper_skb_get_tunnel_opt (skb, opt, size); +} + +/* { dg-final { scan-assembler "call\t29" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c new file mode 100644 index 00000000000..8217b4a17df --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *xfrm_state; + uint32_t index, size; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_get_xfrm_state (skb, index, + xfrm_state, size, flags); +} + +/* { dg-final { scan-assembler "call\t66" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c new file mode 100644 index 00000000000..bcaa43be9de --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *to; + uint32_t offset, len, start_header; + + ret = __builtin_bpf_helper_skb_load_bytes_relative (skb, offset, + to, len, + start_header); +} + +/* { dg-final { scan-assembler "call\t68" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c new file mode 100644 index 00000000000..9da545400c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *to; + uint32_t offset, len; + + ret = __builtin_bpf_helper_skb_load_bytes (skb, offset, to, len); +} + +/* { dg-final { scan-assembler "call\t26" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c b/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c new file mode 100644 index 00000000000..9bb8b8d6e78 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t len; + + ret = __builtin_bpf_helper_skb_pull_data (skb, len); +} + +/* { dg-final { scan-assembler "call\t39" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c new file mode 100644 index 00000000000..21b835f5cef --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *key; + uint32_t size; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_set_tunnel_key (skb, key, size, flags); +} + +/* { dg-final { scan-assembler "call\t21" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c new file mode 100644 index 00000000000..5a0528ec0a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint8_t *opt; + uint32_t size; + + ret = __builtin_bpf_helper_skb_set_tunnel_opt (skb, opt, size); +} + +/* { dg-final { scan-assembler "call\t30" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c new file mode 100644 index 00000000000..a41967cb904 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t offset; + void *from; + uint32_t len; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_store_bytes (skb, offset, from, len, flags); +} + +/* { dg-final { scan-assembler "call\t9" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c b/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c new file mode 100644 index 00000000000..0ccee8bed5c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *map; + uint32_t index; + + ret = __builtin_bpf_helper_skb_under_cgroup (skb, map, index); +} + +/* { dg-final { scan-assembler "call\t33" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c new file mode 100644 index 00000000000..e99a0ac7802 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + + ret = __builtin_bpf_helper_skb_vlan_pop (skb); +} + +/* { dg-final { scan-assembler "call\t19" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c new file mode 100644 index 00000000000..dbe52aee1b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + int16_t vlan_proto; + uint16_t vlan_tci; + + ret = __builtin_bpf_helper_skb_vlan_push (skb, vlan_proto, vlan_tci); +} + +/* { dg-final { scan-assembler "call\t18" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c b/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c new file mode 100644 index 00000000000..bbc4b99a808 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret; + void *ctx, *tuple; + uint32_t tuple_size; + uint64_t netns, flags; + + ret = __builtin_bpf_helper_skc_lookup_tcp (ctx, tuple, + tuple_size, netns, flags); +} + +/* { dg-final { scan-assembler "call\t99" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c b/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c new file mode 100644 index 00000000000..bbb77ef9ad5 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skops, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_sock_hash_update (skops, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t70" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c b/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c new file mode 100644 index 00000000000..301e59e975b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skops, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_sock_map_update (skops, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t53" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c b/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c new file mode 100644 index 00000000000..2056312bcf3 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *bpf_sock; + int argval; + + ret = __builtin_bpf_helper_sock_ops_cb_flags_set (bpf_sock, + argval); +} + +/* { dg-final { scan-assembler "call\t59" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c b/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c new file mode 100644 index 00000000000..4178914ae13 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *lock; + + __builtin_bpf_helper_spin_lock (lock); +} + +/* { dg-final { scan-assembler "call\t93" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c b/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c new file mode 100644 index 00000000000..c2416b66994 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *lock; + + __builtin_bpf_helper_spin_unlock (lock); +} + +/* { dg-final { scan-assembler "call\t94" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-strtol.c b/gcc/testsuite/gcc.target/bpf/helper-strtol.c new file mode 100644 index 00000000000..e15b6d6b968 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-strtol.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *buf; + long res; + uint64_t flags; + size_t buf_len; + + ret = __builtin_bpf_helper_strtol (buf, buf_len, flags, &res); +} + +/* { dg-final { scan-assembler "call\t105" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-strtoul.c b/gcc/testsuite/gcc.target/bpf/helper-strtoul.c new file mode 100644 index 00000000000..bc0d77656d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-strtoul.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *buf; + unsigned long res; + uint64_t flags; + size_t buf_len; + + ret = __builtin_bpf_helper_strtoul (buf, buf_len, flags, &res); +} + +/* { dg-final { scan-assembler "call\t106" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c new file mode 100644 index 00000000000..803584171dd --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + size_t buf_len; + + ret = __builtin_bpf_helper_sysctl_get_current_value (ctx, buf, + buf_len); +} + +/* { dg-final { scan-assembler "call\t102" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c new file mode 100644 index 00000000000..a748b4bf911 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + size_t buf_len; + uint64_t flags; + + ret = __builtin_bpf_helper_sysctl_get_name (ctx, buf, + buf_len, flags); +} + +/* { dg-final { scan-assembler "call\t101" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c new file mode 100644 index 00000000000..2c4835100c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + size_t buf_len; + + ret = __builtin_bpf_helper_sysctl_get_new_value (ctx, buf, + buf_len); +} + +/* { dg-final { scan-assembler "call\t103" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c new file mode 100644 index 00000000000..fc3780da7e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + size_t buf_len; + + ret = __builtin_bpf_helper_sysctl_set_new_value (ctx, buf, + buf_len); +} + +/* { dg-final { scan-assembler "call\t104" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-tail-call.c b/gcc/testsuite/gcc.target/bpf/helper-tail-call.c new file mode 100644 index 00000000000..618064f4aea --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-tail-call.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ctx, *prog_array_map; + uint32_t index; + + __builtin_bpf_helper_tail_call (ctx, prog_array_map, index); +} + +/* { dg-final { scan-assembler "call\t12" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c b/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c new file mode 100644 index 00000000000..95846c6f2d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *sk, *iph, *th; + uint32_t iph_len, th_len; + + ret = __builtin_bpf_helper_tcp_check_syncookie (sk, iph, + iph_len, + th, th_len); +} + +/* { dg-final { scan-assembler "call\t100" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c b/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c new file mode 100644 index 00000000000..ab8f2de05d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret, *sk; + + ret = __builtin_bpf_helper_tcp_sock (sk); +} + +/* { dg-final { scan-assembler "call\t96" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c b/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c new file mode 100644 index 00000000000..fcf9d5c9e50 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + + ret = __builtin_bpf_helper_trace_printk ("foo %d %d", sizeof ("foo %d %d"), 10, 20); +} + +/* { dg-final { scan-assembler "call\t6" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c new file mode 100644 index 00000000000..3dce5434535 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *xdp_md; + int delta; + + ret = __builtin_bpf_helper_xdp_adjust_head (xdp_md, delta); +} + +/* { dg-final { scan-assembler "call\t44" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c new file mode 100644 index 00000000000..38a13748737 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *xdp_md; + int delta; + + ret = __builtin_bpf_helper_xdp_adjust_meta (xdp_md, delta); +} + +/* { dg-final { scan-assembler "call\t54" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c new file mode 100644 index 00000000000..319b65a233d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *xdp_md; + int delta; + + ret = __builtin_bpf_helper_xdp_adjust_tail (xdp_md, delta); +} + +/* { dg-final { scan-assembler "call\t65" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c new file mode 100644 index 00000000000..ce193ec14bf --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + int ancestor_level; + + ret = __builtin_bpf_helper_skb_ancestor_cgroup_id (skb, + ancestor_level); +} + +/* { dg-final { scan-assembler "call\t83" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c b/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c new file mode 100644 index 00000000000..69949f14d0c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +long delta; +long *val; + +void +foo () +{ + __sync_fetch_and_add(val, delta); + __sync_fetch_and_add((int *)val, (int)delta); +} + +/* { dg-final { scan-assembler "xadddw\t.*" } } */ +/* { dg-final { scan-assembler "xaddw\t.*" } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 4d03cc0718b..3db1902b25c 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -526,7 +526,8 @@ proc check_effective_target_trampolines { } { || [istarget nvptx-*-*] || [istarget hppa2.0w-hp-hpux11.23] || [istarget hppa64-hp-hpux11.23] - || [istarget pru-*-*] } { + || [istarget pru-*-*] + || [istarget bpf-*-*] } { return 0; } return 1 @@ -781,7 +782,7 @@ proc add_options_for_tls { flags } { # Return 1 if indirect jumps are supported, 0 otherwise. proc check_effective_target_indirect_jumps {} { - if { [istarget nvptx-*-*] } { + if { [istarget nvptx-*-*] || [istarget bpf-*-*] } { return 0 } return 1 @@ -790,7 +791,7 @@ proc check_effective_target_indirect_jumps {} { # Return 1 if nonlocal goto is supported, 0 otherwise. proc check_effective_target_nonlocal_goto {} { - if { [istarget nvptx-*-*] } { + if { [istarget nvptx-*-*] || [istarget bpf-*-*] } { return 0 } return 1 @@ -799,10 +800,9 @@ proc check_effective_target_nonlocal_goto {} { # Return 1 if global constructors are supported, 0 otherwise. proc check_effective_target_global_constructor {} { - if { [istarget nvptx-*-*] } { - return 0 - } - if { [istarget amdgcn-*-*] } { + if { [istarget nvptx-*-*] + || [istarget amdgcn-*-*] + || [istarget bpf-*-*] } { return 0 } return 1 @@ -825,6 +825,10 @@ proc check_effective_target_return_address {} { if { [istarget nvptx-*-*] } { return 0 } + # No notion of return address in eBPF. + if { [istarget bpf-*-*] } { + return 0 + } # It could be supported on amdgcn, but isn't yet. if { [istarget amdgcn*-*-*] } { return 0 diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index df5d99684e6..fdbc009925e 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,10 @@ +2019-09-09 Jose E. Marchesi + + * config.host: Set cpu_type for bpf-*-* targets. + * config/bpf/t-bpf: Likewise. + * config/bpf/crtn.S: Likewise. + * config/bpf/crti.S: New file. + 2019-09-06 Jim Wilson * config.host (riscv*-*-linux*): Add t-slibgcc-libgcc to tmake_file. diff --git a/libgcc/config.host b/libgcc/config.host index 1db52878a5e..b5826feec46 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -107,6 +107,9 @@ avr-*-*) bfin*-*) cpu_type=bfin ;; +bpf-*-*) + cpu_type=bpf + ;; cr16-*-*) ;; crisv32-*-*) @@ -523,6 +526,10 @@ bfin*-*) tmake_file="$tmake_file bfin/t-bfin t-fdpbit" extra_parts="crtbegin.o crtend.o crti.o crtn.o" ;; +bpf-*-*) + tmake_file="$tmake_file ${cpu_type}/t-${cpu_type}" + extra_parts="crti.o crtn.o" + ;; cr16-*-elf) tmake_file="${tmake_file} cr16/t-cr16 cr16/t-crtlibid t-fdpbit" extra_parts="$extra_parts crti.o crtn.o crtlibid.o" diff --git a/libgcc/config/bpf/crti.S b/libgcc/config/bpf/crti.S new file mode 100644 index 00000000000..e69de29bb2d diff --git a/libgcc/config/bpf/crtn.S b/libgcc/config/bpf/crtn.S new file mode 100644 index 00000000000..e69de29bb2d diff --git a/libgcc/config/bpf/t-bpf b/libgcc/config/bpf/t-bpf new file mode 100644 index 00000000000..88129a78f61 --- /dev/null +++ b/libgcc/config/bpf/t-bpf @@ -0,0 +1,23 @@ +LIB2ADDEH = + +crti.o: $(srcdir)/config/bpf/crti.S + $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< + +crtn.o: $(srcdir)/config/bpf/crtn.S + $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< + +# Some of the functions defined in libgcc2 exceed the eBPF stack +# limit, or other restrictions imposed by this peculiar target. +# Therefore we have to exclude them here. +# +# Patterns in bpf.md must guarantee that no calls to the excluded +# functions are ever generated, and compiler tests should make sure +# this holds. +# +# Note that the modes in the function names below are misleading: di +# means TImode. +LIB2FUNCS_EXCLUDE = _mulvdi3 _divdi3 _moddi3 _divmoddi4 _udivdi3 _umoddi3 \ + _udivmoddi4 + +# Prevent building "advanced" stuff (for example, gcov support). +INHIBIT_LIBC_CFLAGS = -Dinhibit_libc