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
This commit is contained in:
Jose E. Marchesi 2019-09-09 12:13:23 +02:00
parent a5362c6aea
commit 91dfef9610
227 changed files with 5454 additions and 17 deletions

View File

@ -1,3 +1,13 @@
2019-09-09 Jose E. Marchesi <jose.marchesi@oracle.com>
* MAINTAINERS: Add myself as the maintainer of the eBPF port.
Remove myself from Write After Approval section.
2019-09-09 Jose E. Marchesi <jose.marchesi@oracle.com>
* configure.ac: Support for bpf-*-* targets.
* configure: Regenerate.
2019-09-09 Jose E. Marchesi <jose.marchesi@oracle.com>
* config.sub: Import upstream version 2019-06-30.

View File

@ -57,6 +57,7 @@ arm port Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
arm port Kyrylo Tkachov <kyrylo.tkachov@arm.com>
avr port Denis Chertykov <chertykov@gmail.com>
bfin port Jie Zhang <jzhang918@gmail.com>
bpf port Jose E. Marchesi <jose.marchesi@oracle.com>
c6x port Bernd Schmidt <bernds_cb1@t-online.de>
cris port Hans-Peter Nilsson <hp@axis.com>
c-sky port Xianmiao Qu <xianmiao_qu@c-sky.com>
@ -494,7 +495,6 @@ Luis Machado <luisgpm@br.ibm.com>
Ziga Mahkovec <ziga.mahkovec@klika.si>
Matthew Malcomson <matthew.malcomson@arm.com>
Mikhail Maltsev <maltsevm@gmail.com>
Jose E. Marchesi <jose.marchesi@oracle.com>
Patrick Marlier <patrick.marlier@gmail.com>
Simon Martin <simartin@users.sourceforge.net>
Alejandro Martinez <alejandro.martinezvicente@arm.com>

54
configure vendored
View File

@ -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 <http://gcc.gnu.org/ml/gcc-patches/2004-11/msg00572.html>.
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"
;;

View File

@ -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 <http://gcc.gnu.org/ml/gcc-patches/2004-11/msg00572.html>.
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"
;;

View File

@ -1,3 +1,7 @@
2019-09-09 Jose E. Marchesi <jemarch@gnu.org>
* config-list.mk (LIST): Disable go in bpf-*-* targets.
2019-09-04 Martin Liska <mliska@suse.cz>
* mklog: Do not print changed functions for

View File

@ -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=""; \
;; \
*) \

View File

@ -1,3 +1,26 @@
2019-09-09 Jose E. Marchesi <jose.marchesi@oracle.com>
* 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 <jose.marchesi@oracle.com>
* 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 <jose.marchesi@oracle.com>
* doc/sourcebuild.texi (Effective-Target Keywords): Document

View File

@ -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
<http://www.gnu.org/licenses/>. */
#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;

View File

@ -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 "

View File

@ -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
<http://www.gnu.org/licenses/>. */
/* 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:
*/

View File

@ -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
<http://www.gnu.org/licenses/>. */
/* 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 */

56
gcc/config/bpf/bpf-opts.h Normal file
View File

@ -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
<http://www.gnu.org/licenses/>. */
#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 */

View File

@ -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
<http://www.gnu.org/licenses/>. */
#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 */

948
gcc/config/bpf/bpf.c Normal file
View File

@ -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
<http://www.gnu.org/licenses/>. */
#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<machine_function> ();
}
/* 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"

539
gcc/config/bpf/bpf.h Normal file
View File

@ -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
<http://www.gnu.org/licenses/>. */
#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 */

497
gcc/config/bpf/bpf.md Normal file
View File

@ -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
;; <http://www.gnu.org/licenses/>.
(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 "add<AM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
;;; Subtraction
;; Note that subtractions of constants become additions, so there is
;; no need to handle immediate operands in the subMODE3 insns.
(define_insn "sub<AM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
;;; Negation
(define_insn "neg<AM:mode>2"
[(set (match_operand:AM 0 "register_operand" "=r")
(neg:AM (match_operand:AM 1 "register_operand" " 0")))]
""
"neg<msuffix>\t%0"
[(set_attr "type" "<mtype>")])
;;; Multiplication
(define_insn "mul<AM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
(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 "udiv<AM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
;;; Modulus
;; Note that eBPF doesn't provide instructions for signed integer
;; remainder.
(define_insn "umod<AM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
;;; Logical AND
(define_insn "and<AM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
;;; Logical inclusive-OR
(define_insn "ior<AM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
;;; Logical exclusive-OR
(define_insn "xor<AM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
;;;; 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<MM:mode>"
[(set (match_operand:MM 0 "general_operand")
(match_operand:MM 1 "general_operand"))]
""
"
{
if (!register_operand(operands[0], <MM:MODE>mode)
&& !register_operand(operands[1], <MM:MODE>mode))
operands[1] = force_reg (<MM:MODE>mode, operands[1]);
}")
(define_insn "*mov<MM:mode>"
[(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<mop>\t%0,%1
mov\t%0,%1
lddw\t%0,%1
stx<mop>\t%0,%1
st<mop>\t%0,%1"
[(set_attr "type" "ldx,alu,alu,stx,st")])
;;;; Shifts
(define_mode_iterator SIM [SI DI])
(define_insn "ashr<SIM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
(define_insn "ashl<SIM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
(define_insn "lshr<SIM:mode>3"
[(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<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
;;;; 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<ldop>"
[(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<ldop>\t%0,%1"
[(set_attr "type" "ld")])
(define_insn "ldabs<ldop>"
[(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<ldop>\t%0"
[(set_attr "type" "ld")])
;;;; Atomic increments
(define_mode_iterator AMO [SI DI])
(define_insn "atomic_add<AMO:mode>"
[(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<mop>\t%0,%1"
[(set_attr "type" "xadd")])

123
gcc/config/bpf/bpf.opt Normal file
View File

@ -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
; <http://www.gnu.org/licenses/>.
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.

View File

@ -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
;; <http://www.gnu.org/licenses/>.
(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"))

View File

@ -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
;; <http://www.gnu.org/licenses/>.
(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"))

0
gcc/config/bpf/t-bpf Normal file
View File

View File

@ -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

View File

@ -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

View File

@ -1,3 +1,218 @@
2019-09-09 Jose E. Marchesi <jose.marchesi@oracle.com>
* 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 <jose.marchesi@oracle.com>
* 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 <jose.marchesi@oracle.com>
* 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 <jose.marchesi@oracle.com>
* lib/target-supports.exp (check_effective_target_indirect_calls):

View File

@ -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;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
struct utsname {
char sysname[32 ];
char version[32 ];

View File

@ -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" } */

View File

@ -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. */

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef struct _ScaleRec *ScaleWidget;
typedef struct
{

View File

@ -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)

View File

@ -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__);

View File

@ -1,5 +1,7 @@
/* Testcase provided by HUAWEI. */
#include <stdio.h>
extern int printf (const char * __format, ...);
int main()
{
int cur_k;

View File

@ -1,4 +1,6 @@
/* { dg-require-effective-target alloca } */
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
main ()
{
char *a;

View File

@ -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:;}

View File

@ -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;

View File

@ -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)

View File

@ -1,4 +1,5 @@
/* { dg-require-effective-target untyped_assembly } */
/* { dg-skip-if "no __builtin_apply in eBPF" { bpf-*-* } } */
g (a, b) {}

View File

@ -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;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef struct _geom_elem {
double coeffs[6];
} pGeomDefRec, *pGeomDefPtr;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef __SIZE_TYPE__ size_t;
typedef void *XtPointer;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "no string.h in eBPF" { bpf-*-* } } */
#define __USE_STRING_INLINES
#include <string.h>

View File

@ -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;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define type short
type glob0, glob1;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define E0 ((type *)10000000)
#define reg0 r0
#define indreg0 (*p0)

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define type signed char
type glob0, glob1;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define E0 ((type *)10000000)
#define reg0 r0
#define indreg0 (*p0)

View File

@ -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

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define type int
type glob0, glob1;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define E0 ((type *)10000000)
#define reg0 r0
#define indreg0 (*p0)

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define type unsigned short
type glob0, glob1;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define type unsigned char
type glob0, glob1;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define type unsigned int
type glob0, glob1;

View File

@ -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)

View File

@ -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) \

View File

@ -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;

View File

@ -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)

View File

@ -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)
{

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
typedef struct
{
char c[510];

View File

@ -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;

View File

@ -1,3 +1,4 @@
/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
struct w
{

View File

@ -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;

View File

@ -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;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef __SIZE_TYPE__ size_t;
typedef struct {
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -1,4 +1,5 @@
/* PR c/54428 */
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef double _Complex C;

View File

@ -1,4 +1,5 @@
/* PR tree-optimization/54713 */
/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
#ifndef N
#define N 8

View File

@ -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

View File

@ -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, \

View File

@ -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
{

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef int v8si __attribute__ ((vector_size (32)));
int

View File

@ -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)));

View File

@ -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)));

View File

@ -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;

View File

@ -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;

View File

@ -1,4 +1,5 @@
/* PR middle-end/86122 */
/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
_Complex int
foo (_Complex int x)

View File

@ -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;
{

View File

@ -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;

View File

@ -1,3 +1,5 @@
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
struct foo
{
int a, b, c, d;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -2,7 +2,7 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef struct test
{

View File

@ -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) {}

View File

@ -1,5 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
/* { dg-skip-if "no stdlib.h in eBPF" { bpf-*-* } } */
#include <stdlib.h>
struct s {
unsigned short f: 16;

View File

@ -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

View File

@ -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

View File

@ -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;

Some files were not shown because too many files have changed in this diff Show More