mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-27 05:44:15 +08:00
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:
parent
a5362c6aea
commit
91dfef9610
10
ChangeLog
10
ChangeLog
@ -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.
|
||||
|
@ -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
54
configure
vendored
@ -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"
|
||||
;;
|
||||
|
54
configure.ac
54
configure.ac
@ -638,6 +638,9 @@ case "${target}" in
|
||||
# No hosted I/O support.
|
||||
noconfigdirs="$noconfigdirs target-libssp"
|
||||
;;
|
||||
bpf-*-*)
|
||||
noconfigdirs="$noconfigdirs target-libssp"
|
||||
;;
|
||||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
noconfigdirs="$noconfigdirs target-libssp"
|
||||
;;
|
||||
@ -672,12 +675,43 @@ if test "${ENABLE_LIBSTDCXX}" = "default" ; then
|
||||
avr-*-*)
|
||||
noconfigdirs="$noconfigdirs target-libstdc++-v3"
|
||||
;;
|
||||
bpf-*-*)
|
||||
noconfigdirs="$noconfigdirs target-libstdc++-v3"
|
||||
;;
|
||||
ft32-*-*)
|
||||
noconfigdirs="$noconfigdirs target-libstdc++-v3"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Disable C++ on systems where it is known to not work.
|
||||
# For testing, you can override this with --enable-languages=c++.
|
||||
case ,${enable_languages}, in
|
||||
*,c++,*)
|
||||
;;
|
||||
*)
|
||||
case "${target}" in
|
||||
bpf-*-*)
|
||||
unsupported_languages="$unsupported_languages c++"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Disable Objc on systems where it is known to not work.
|
||||
# For testing, you can override this with --enable-languages=objc.
|
||||
case ,${enable_languages}, in
|
||||
*,objc,*)
|
||||
;;
|
||||
*)
|
||||
case "${target}" in
|
||||
bpf-*-*)
|
||||
unsupported_languages="$unsupported_languages objc"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Disable D on systems where it is known to not work.
|
||||
# For testing, you can override this with --enable-languages=d.
|
||||
case ,${enable_languages}, in
|
||||
@ -686,6 +720,9 @@ case ,${enable_languages}, in
|
||||
*)
|
||||
case "${target}" in
|
||||
*-*-darwin*)
|
||||
unsupported_languages="$unsupported_languages d"
|
||||
;;
|
||||
bpf-*-*)
|
||||
unsupported_languages="$unsupported_languages d"
|
||||
;;
|
||||
esac
|
||||
@ -715,6 +752,9 @@ case "${target}" in
|
||||
# See <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"
|
||||
;;
|
||||
|
@ -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
|
||||
|
@ -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=""; \
|
||||
;; \
|
||||
*) \
|
||||
|
@ -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
|
||||
|
55
gcc/common/config/bpf/bpf-common.c
Normal file
55
gcc/common/config/bpf/bpf-common.c
Normal 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;
|
@ -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 "
|
||||
|
194
gcc/config/bpf/bpf-helpers.def
Normal file
194
gcc/config/bpf/bpf-helpers.def
Normal 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:
|
||||
*/
|
327
gcc/config/bpf/bpf-helpers.h
Normal file
327
gcc/config/bpf/bpf-helpers.h
Normal 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
56
gcc/config/bpf/bpf-opts.h
Normal 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 */
|
33
gcc/config/bpf/bpf-protos.h
Normal file
33
gcc/config/bpf/bpf-protos.h
Normal 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
948
gcc/config/bpf/bpf.c
Normal 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
539
gcc/config/bpf/bpf.h
Normal 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
497
gcc/config/bpf/bpf.md
Normal 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
123
gcc/config/bpf/bpf.opt
Normal 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.
|
32
gcc/config/bpf/constraints.md
Normal file
32
gcc/config/bpf/constraints.md
Normal 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"))
|
||||
|
64
gcc/config/bpf/predicates.md
Normal file
64
gcc/config/bpf/predicates.md
Normal 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
0
gcc/config/bpf/t-bpf
Normal 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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
struct utsname {
|
||||
char sysname[32 ];
|
||||
char version[32 ];
|
||||
|
@ -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" } */
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
typedef struct _ScaleRec *ScaleWidget;
|
||||
typedef struct
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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__);
|
||||
|
@ -1,5 +1,7 @@
|
||||
/* Testcase provided by HUAWEI. */
|
||||
#include <stdio.h>
|
||||
|
||||
extern int printf (const char * __format, ...);
|
||||
|
||||
int main()
|
||||
{
|
||||
int cur_k;
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* { dg-require-effective-target alloca } */
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
main ()
|
||||
{
|
||||
char *a;
|
||||
|
@ -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:;}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* { dg-require-effective-target untyped_assembly } */
|
||||
/* { dg-skip-if "no __builtin_apply in eBPF" { bpf-*-* } } */
|
||||
|
||||
g (a, b) {}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
typedef struct _geom_elem {
|
||||
double coeffs[6];
|
||||
} pGeomDefRec, *pGeomDefPtr;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef void *XtPointer;
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "no string.h in eBPF" { bpf-*-* } } */
|
||||
|
||||
#define __USE_STRING_INLINES
|
||||
#include <string.h>
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define type short
|
||||
|
||||
type glob0, glob1;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define E0 ((type *)10000000)
|
||||
#define reg0 r0
|
||||
#define indreg0 (*p0)
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define type signed char
|
||||
|
||||
type glob0, glob1;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define E0 ((type *)10000000)
|
||||
#define reg0 r0
|
||||
#define indreg0 (*p0)
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define type int
|
||||
|
||||
type glob0, glob1;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define E0 ((type *)10000000)
|
||||
#define reg0 r0
|
||||
#define indreg0 (*p0)
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define type unsigned short
|
||||
|
||||
type glob0, glob1;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define type unsigned char
|
||||
|
||||
type glob0, glob1;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
#define type unsigned int
|
||||
|
||||
type glob0, glob1;
|
||||
|
@ -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)
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char c[510];
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
|
||||
|
||||
struct w
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef struct {
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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__
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* PR c/54428 */
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
typedef double _Complex C;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* PR tree-optimization/54713 */
|
||||
/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
|
||||
|
||||
#ifndef N
|
||||
#define N 8
|
||||
|
@ -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
|
||||
|
@ -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, \
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
typedef int v8si __attribute__ ((vector_size (32)));
|
||||
|
||||
int
|
||||
|
@ -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)));
|
||||
|
@ -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)));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* PR middle-end/86122 */
|
||||
/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
|
||||
|
||||
_Complex int
|
||||
foo (_Complex int x)
|
||||
|
@ -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;
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
struct foo
|
||||
{
|
||||
int a, b, c, d;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
|
||||
|
||||
typedef struct test
|
||||
{
|
||||
|
@ -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) {}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user