]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
GCC port for eBPF
authorJose E. Marchesi <jemarch@gcc.gnu.org>
Mon, 9 Sep 2019 10:13:23 +0000 (12:13 +0200)
committerJose E. Marchesi <jemarch@gcc.gnu.org>
Mon, 9 Sep 2019 10:13:23 +0000 (12:13 +0200)
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

227 files changed:
ChangeLog
MAINTAINERS
configure
configure.ac
contrib/ChangeLog
contrib/config-list.mk
gcc/ChangeLog
gcc/common/config/bpf/bpf-common.c [new file with mode: 0644]
gcc/config.gcc
gcc/config/bpf/bpf-helpers.def [new file with mode: 0644]
gcc/config/bpf/bpf-helpers.h [new file with mode: 0644]
gcc/config/bpf/bpf-opts.h [new file with mode: 0644]
gcc/config/bpf/bpf-protos.h [new file with mode: 0644]
gcc/config/bpf/bpf.c [new file with mode: 0644]
gcc/config/bpf/bpf.h [new file with mode: 0644]
gcc/config/bpf/bpf.md [new file with mode: 0644]
gcc/config/bpf/bpf.opt [new file with mode: 0644]
gcc/config/bpf/constraints.md [new file with mode: 0644]
gcc/config/bpf/predicates.md [new file with mode: 0644]
gcc/config/bpf/t-bpf [new file with mode: 0644]
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20000211-1.c
gcc/testsuite/gcc.c-torture/compile/20000403-1.c
gcc/testsuite/gcc.c-torture/compile/20000804-1.c
gcc/testsuite/gcc.c-torture/compile/20001226-1.c
gcc/testsuite/gcc.c-torture/compile/20030903-1.c
gcc/testsuite/gcc.c-torture/compile/20031125-1.c
gcc/testsuite/gcc.c-torture/compile/20040101-1.c
gcc/testsuite/gcc.c-torture/compile/20040317-2.c
gcc/testsuite/gcc.c-torture/compile/20040726-1.c
gcc/testsuite/gcc.c-torture/compile/20051216-1.c
gcc/testsuite/gcc.c-torture/compile/20101217-1.c
gcc/testsuite/gcc.c-torture/compile/900313-1.c
gcc/testsuite/gcc.c-torture/compile/920501-7.c
gcc/testsuite/gcc.c-torture/compile/920625-1.c
gcc/testsuite/gcc.c-torture/compile/930421-1.c
gcc/testsuite/gcc.c-torture/compile/930623-1.c
gcc/testsuite/gcc.c-torture/compile/961004-1.c
gcc/testsuite/gcc.c-torture/compile/980504-1.c
gcc/testsuite/gcc.c-torture/compile/980816-1.c
gcc/testsuite/gcc.c-torture/compile/990625-1.c
gcc/testsuite/gcc.c-torture/compile/DFcmp.c
gcc/testsuite/gcc.c-torture/compile/HIcmp.c
gcc/testsuite/gcc.c-torture/compile/HIset.c
gcc/testsuite/gcc.c-torture/compile/QIcmp.c
gcc/testsuite/gcc.c-torture/compile/QIset.c
gcc/testsuite/gcc.c-torture/compile/SFset.c
gcc/testsuite/gcc.c-torture/compile/SIcmp.c
gcc/testsuite/gcc.c-torture/compile/SIset.c
gcc/testsuite/gcc.c-torture/compile/UHIcmp.c
gcc/testsuite/gcc.c-torture/compile/UQIcmp.c
gcc/testsuite/gcc.c-torture/compile/USIcmp.c
gcc/testsuite/gcc.c-torture/compile/consec.c
gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c
gcc/testsuite/gcc.c-torture/compile/lll.c
gcc/testsuite/gcc.c-torture/compile/parms.c
gcc/testsuite/gcc.c-torture/compile/pass.c
gcc/testsuite/gcc.c-torture/compile/poor.c
gcc/testsuite/gcc.c-torture/compile/pp.c
gcc/testsuite/gcc.c-torture/compile/pr25311.c
gcc/testsuite/gcc.c-torture/compile/pr32399.c
gcc/testsuite/gcc.c-torture/compile/pr34091.c
gcc/testsuite/gcc.c-torture/compile/pr34688.c
gcc/testsuite/gcc.c-torture/compile/pr37258.c
gcc/testsuite/gcc.c-torture/compile/pr37327.c
gcc/testsuite/gcc.c-torture/compile/pr37381.c
gcc/testsuite/gcc.c-torture/compile/pr37669-2.c
gcc/testsuite/gcc.c-torture/compile/pr37669.c
gcc/testsuite/gcc.c-torture/compile/pr37742-3.c
gcc/testsuite/gcc.c-torture/compile/pr39928-1.c
gcc/testsuite/gcc.c-torture/compile/pr44063.c
gcc/testsuite/gcc.c-torture/compile/pr48596.c
gcc/testsuite/gcc.c-torture/compile/pr51856.c
gcc/testsuite/gcc.c-torture/compile/pr54428.c
gcc/testsuite/gcc.c-torture/compile/pr54713-1.c
gcc/testsuite/gcc.c-torture/compile/pr54713-2.c
gcc/testsuite/gcc.c-torture/compile/pr54713-3.c
gcc/testsuite/gcc.c-torture/compile/pr55921.c
gcc/testsuite/gcc.c-torture/compile/pr70061.c
gcc/testsuite/gcc.c-torture/compile/pr70240.c
gcc/testsuite/gcc.c-torture/compile/pr70355.c
gcc/testsuite/gcc.c-torture/compile/pr82052.c
gcc/testsuite/gcc.c-torture/compile/pr83487.c
gcc/testsuite/gcc.c-torture/compile/pr86122.c
gcc/testsuite/gcc.c-torture/compile/pret-arg.c
gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c
gcc/testsuite/gcc.c-torture/compile/structret.c
gcc/testsuite/gcc.c-torture/compile/uuarg.c
gcc/testsuite/gcc.dg/20001009-1.c
gcc/testsuite/gcc.dg/20020418-1.c
gcc/testsuite/gcc.dg/20020426-2.c
gcc/testsuite/gcc.dg/20020430-1.c
gcc/testsuite/gcc.dg/20040306-1.c
gcc/testsuite/gcc.dg/20040622-2.c
gcc/testsuite/gcc.dg/20050603-2.c
gcc/testsuite/gcc.dg/20050629-1.c
gcc/testsuite/gcc.dg/20061026.c
gcc/testsuite/gcc.dg/Warray-bounds-3.c
gcc/testsuite/gcc.dg/Warray-bounds-30.c
gcc/testsuite/gcc.dg/Wframe-larger-than-2.c
gcc/testsuite/gcc.dg/Wframe-larger-than.c
gcc/testsuite/gcc.dg/Wrestrict-11.c
gcc/testsuite/gcc.dg/builtins-config.h
gcc/testsuite/gcc.target/bpf/bpf.exp [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/builtin-load.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/constant-calls.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/diag-funargs-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/diag-funargs-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/diag-funargs.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/diag-indcalls.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-bind.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-csum-diff.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-csum-update.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-current-task.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-stack.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-get-stackid.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-getsockopt.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-override-return.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-probe-read.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-redirect-map.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-set-hash.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-setsockopt.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-release.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-spin-lock.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-strtol.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-strtoul.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-tail-call.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-trace-printk.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c [new file with mode: 0644]
gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp
libgcc/ChangeLog
libgcc/config.host
libgcc/config/bpf/crti.S [new file with mode: 0644]
libgcc/config/bpf/crtn.S [new file with mode: 0644]
libgcc/config/bpf/t-bpf [new file with mode: 0644]

index f7913105e5ce1a7c0b5c966afb9625c101a5eb09..3685a2472db39c5f8601707cb18a2475dcc46338 100644 (file)
--- a/ChangeLog
+++ b/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.
index 109ac32e7aec2568bac1c526922e0dd5947a327d..93c9bb4357d4a4e61f8051f12fd513e658c50a7c 100644 (file)
@@ -57,6 +57,7 @@ arm port              Ramana Radhakrishnan    <ramana.radhakrishnan@arm.com>
 arm port               Kyrylo Tkachov          <kyrylo.tkachov@arm.com>
 avr port               Denis Chertykov         <chertykov@gmail.com>
 bfin port              Jie Zhang               <jzhang918@gmail.com>
+bpf port               Jose E. Marchesi        <jose.marchesi@oracle.com>
 c6x port               Bernd Schmidt           <bernds_cb1@t-online.de>
 cris port              Hans-Peter Nilsson      <hp@axis.com>
 c-sky port             Xianmiao Qu             <xianmiao_qu@c-sky.com>
@@ -494,7 +495,6 @@ Luis Machado                                        <luisgpm@br.ibm.com>
 Ziga Mahkovec                                  <ziga.mahkovec@klika.si>
 Matthew Malcomson                              <matthew.malcomson@arm.com>
 Mikhail Maltsev                                        <maltsevm@gmail.com>
-Jose E. Marchesi                               <jose.marchesi@oracle.com>
 Patrick Marlier                                        <patrick.marlier@gmail.com>
 Simon Martin                                   <simartin@users.sourceforge.net>
 Alejandro Martinez                             <alejandro.martinezvicente@arm.com>
index c3ec920df13acd677664abf403420c8561cb2929..aec9186b2b0123d3088b69eb1ee541567654953e 100755 (executable)
--- a/configure
+++ b/configure
@@ -3357,6 +3357,9 @@ case "${target}" in
     # No hosted I/O support.
     noconfigdirs="$noconfigdirs target-libssp"
     ;;
+  bpf-*-*)
+    noconfigdirs="$noconfigdirs target-libssp"
+    ;;
   powerpc-*-aix* | rs6000-*-aix*)
     noconfigdirs="$noconfigdirs target-libssp"
     ;;
@@ -3391,12 +3394,43 @@ if test "${ENABLE_LIBSTDCXX}" = "default" ; then
     avr-*-*)
       noconfigdirs="$noconfigdirs target-libstdc++-v3"
       ;;
+    bpf-*-*)
+      noconfigdirs="$noconfigdirs target-libstdc++-v3"
+      ;;
     ft32-*-*)
       noconfigdirs="$noconfigdirs target-libstdc++-v3"
       ;;
   esac
 fi
 
+# Disable C++ on systems where it is known to not work.
+# For testing, you can override this with --enable-languages=c++.
+case ,${enable_languages}, in
+  *,c++,*)
+    ;;
+  *)
+      case "${target}" in
+        bpf-*-*)
+          unsupported_languages="$unsupported_languages c++"
+          ;;
+      esac
+      ;;
+esac
+
+# Disable Objc on systems where it is known to not work.
+# For testing, you can override this with --enable-languages=objc.
+case ,${enable_languages}, in
+  *,objc,*)
+    ;;
+  *)
+      case "${target}" in
+        bpf-*-*)
+          unsupported_languages="$unsupported_languages objc"
+          ;;
+      esac
+      ;;
+esac
+
 # Disable D on systems where it is known to not work.
 # For testing, you can override this with --enable-languages=d.
 case ,${enable_languages}, in
@@ -3405,6 +3439,9 @@ case ,${enable_languages}, in
   *)
     case "${target}" in
       *-*-darwin*)
+       unsupported_languages="$unsupported_languages d"
+        ;;
+      bpf-*-*)
        unsupported_languages="$unsupported_languages d"
        ;;
     esac
@@ -3437,6 +3474,9 @@ case "${target}" in
     # See <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"
     ;;
index 1fe97c001cc459f972b9248fbf7285a9c8cbc155..b8ce2ad20b9d03e42731252a9ec2a8417c13e566 100644 (file)
@@ -638,6 +638,9 @@ case "${target}" in
     # No hosted I/O support.
     noconfigdirs="$noconfigdirs target-libssp"
     ;;
+  bpf-*-*)
+    noconfigdirs="$noconfigdirs target-libssp"
+    ;;
   powerpc-*-aix* | rs6000-*-aix*)
     noconfigdirs="$noconfigdirs target-libssp"
     ;;
@@ -672,12 +675,43 @@ if test "${ENABLE_LIBSTDCXX}" = "default" ; then
     avr-*-*)
       noconfigdirs="$noconfigdirs target-libstdc++-v3"
       ;;
+    bpf-*-*)
+      noconfigdirs="$noconfigdirs target-libstdc++-v3"
+      ;;
     ft32-*-*)
       noconfigdirs="$noconfigdirs target-libstdc++-v3"
       ;;
   esac
 fi
 
+# Disable C++ on systems where it is known to not work.
+# For testing, you can override this with --enable-languages=c++.
+case ,${enable_languages}, in
+  *,c++,*)
+    ;;
+  *)
+      case "${target}" in
+        bpf-*-*)
+          unsupported_languages="$unsupported_languages c++"
+          ;;
+      esac
+      ;;
+esac
+
+# Disable Objc on systems where it is known to not work.
+# For testing, you can override this with --enable-languages=objc.
+case ,${enable_languages}, in
+  *,objc,*)
+    ;;
+  *)
+      case "${target}" in
+        bpf-*-*)
+          unsupported_languages="$unsupported_languages objc"
+          ;;
+      esac
+      ;;
+esac
+
 # Disable D on systems where it is known to not work.
 # For testing, you can override this with --enable-languages=d.
 case ,${enable_languages}, in
@@ -686,6 +720,9 @@ case ,${enable_languages}, in
   *)
     case "${target}" in
       *-*-darwin*)
+       unsupported_languages="$unsupported_languages d"
+        ;;
+      bpf-*-*)
        unsupported_languages="$unsupported_languages d"
        ;;
     esac
@@ -715,6 +752,9 @@ case "${target}" in
     # See <http://gcc.gnu.org/ml/gcc-patches/2004-11/msg00572.html>.
     unsupported_languages="$unsupported_languages fortran"
     ;;
+  bpf-*-*)
+    unsupported_languages="$unsupported_languages fortran"
+    ;;
 esac
 
 # Disable libffi for some systems.
@@ -761,6 +801,9 @@ case "${target}" in
   arm*-*-symbianelf*)
     noconfigdirs="$noconfigdirs target-libffi"
     ;;
+  bpf-*-*)
+    noconfigdirs="$noconfigdirs target-libffi"
+    ;;
   cris-*-* | crisv32-*-*)
     case "${target}" in
       *-*-linux*)
@@ -807,7 +850,7 @@ esac
 # Disable the go frontend on systems where it is known to not work. Please keep
 # this in sync with contrib/config-list.mk.
 case "${target}" in
-*-*-darwin* | *-*-cygwin* | *-*-mingw*)
+*-*-darwin* | *-*-cygwin* | *-*-mingw* | bpf-* )
     unsupported_languages="$unsupported_languages go"
     ;;
 esac
@@ -823,6 +866,9 @@ if test x$enable_libgo = x; then
     *-*-cygwin* | *-*-mingw*)
        noconfigdirs="$noconfigdirs target-libgo"
        ;;
+    bpf-*-*)
+        noconfigdirs="$noconfigdirs target-libgo"
+        ;;
     esac
 fi
 
@@ -894,6 +940,9 @@ case "${target}" in
   sparc-*-sunos4*)
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     ;;
+  bpf-*-*)
+    noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+    ;;
   *-*-aix*)
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     ;;
@@ -1007,6 +1056,9 @@ case "${target}" in
     # newlib is not 64 bit ready
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
     ;;
+  bpf-*-*)
+    noconfigdirs="$noconfigdirs target-libobjc target-libbacktrace"
+    ;;
   sh*-*-pe|mips*-*-pe|*arm-wince-pe)
     noconfigdirs="$noconfigdirs tcl tk itcl libgui sim"
     ;;
index 743fe00861f6fea372681f23a8f542eb0b5dfe43..0e473d63c222e289cdbe0fc5a079f193876d3347 100644 (file)
@@ -1,3 +1,7 @@
+2019-09-09  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * config-list.mk (LIST): Disable go in bpf-*-* targets.
+
 2019-09-04  Martin Liska  <mliska@suse.cz>
 
        * mklog: Do not print changed functions for
index 8c37cdb628c5c75265ad8be57f723fc95d2b427a..a5f5d7bbd5ad86af75b60b6137f831f4d8a4e941 100644 (file)
@@ -40,6 +40,7 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \
   arm-linux-androideabi arm-uclinux_eabi arm-eabi arm-rtems \
   arm-symbianelf avr-elf \
   bfin-elf bfin-uclinux bfin-linux-uclibc bfin-rtems bfin-openbsd \
+  bpf-unknown-none \
   c6x-elf c6x-uclinux cr16-elf cris-elf cris-linux crisv32-elf crisv32-linux \
   csky-elf csky-linux-gnu \
   epiphany-elf epiphany-elfOPT-with-stack-offset=16 fido-elf \
@@ -123,7 +124,7 @@ $(LIST): make-log-dir
                TGT=`echo $@ | awk 'BEGIN { FS = "OPT" }; { print $$1 }'` &&                    \
                TGT=`$(GCC_SRC_DIR)/config.sub $$TGT` &&                                        \
                case $$TGT in                                                                   \
-                       *-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix*)                      \
+                       *-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix* | bpf-*-*)                    \
                                ADDITIONAL_LANGUAGES="";                                        \
                                ;;                                                              \
                        *)                                                                      \
index cb28809b556444c323b7bf4148aa0df444afa4df..34b2f620b8a3119e258a3e8a3843f29d89d63d9d 100644 (file)
@@ -1,3 +1,26 @@
+2019-09-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       * doc/invoke.texi (Option Summary): Cover eBPF.
+       (eBPF Options): New section.
+       * doc/extend.texi (BPF Built-in Functions): Likewise.
+       (BPF Kernel Helpers): Likewise.
+
+2019-09-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       * config.gcc: Support for bpf-*-* targets.
+       * common/config/bpf/bpf-common.c: New file.
+       * config/bpf/t-bpf: Likewise.
+       * config/bpf/predicates.md: Likewise.
+       * config/bpf/constraints.md: Likewise.
+       * config/bpf/bpf.opt: Likewise.
+       * config/bpf/bpf.md: Likewise.
+       * config/bpf/bpf.h: Likewise.
+       * config/bpf/bpf.c: Likewise.
+       * config/bpf/bpf-protos.h: Likewise.
+       * config/bpf/bpf-opts.h: Likewise.
+       * config/bpf/bpf-helpers.h: Likewise.
+       * config/bpf/bpf-helpers.def: Likewise.
+
 2019-09-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
        * doc/sourcebuild.texi (Effective-Target Keywords): Document
diff --git a/gcc/common/config/bpf/bpf-common.c b/gcc/common/config/bpf/bpf-common.c
new file mode 100644 (file)
index 0000000..0d04f21
--- /dev/null
@@ -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;
index 94a36083db051c039231e76a96410efe93b6d145..0eba7ca1d4d3436ceb765c01c49d6664463fe7cc 100644 (file)
@@ -360,6 +360,9 @@ avr-*-*)
 bfin*-*)
        cpu_type=bfin
        ;;
+bpf-*-*)
+       cpu_type=bpf
+       ;;
 crisv32-*)
        cpu_type=cris
        ;;
@@ -1308,6 +1311,12 @@ bfin*-*)
        use_collect2=no
        use_gcc_stdint=wrap
        ;;
+bpf-*-*)
+        tmake_file="${tmake_file} bpf/t-bpf"
+        use_collect2=no
+        extra_headers="bpf-helpers.h"
+        use_gcc_stdint=provide
+        ;;
 cr16-*-elf)
         tm_file="elfos.h ${tm_file} newlib-stdint.h"
         tmake_file="${tmake_file} cr16/t-cr16 "
diff --git a/gcc/config/bpf/bpf-helpers.def b/gcc/config/bpf/bpf-helpers.def
new file mode 100644 (file)
index 0000000..cd06402
--- /dev/null
@@ -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:
+*/
diff --git a/gcc/config/bpf/bpf-helpers.h b/gcc/config/bpf/bpf-helpers.h
new file mode 100644 (file)
index 0000000..1427543
--- /dev/null
@@ -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 */
diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h
new file mode 100644 (file)
index 0000000..9f210a1
--- /dev/null
@@ -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 */
diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
new file mode 100644 (file)
index 0000000..3a835f4
--- /dev/null
@@ -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 */
diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c
new file mode 100644 (file)
index 0000000..8b2a592
--- /dev/null
@@ -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"
diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
new file mode 100644 (file)
index 0000000..70ad818
--- /dev/null
@@ -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 */
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
new file mode 100644 (file)
index 0000000..4c79522
--- /dev/null
@@ -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")])
diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
new file mode 100644 (file)
index 0000000..e61cf95
--- /dev/null
@@ -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.
diff --git a/gcc/config/bpf/constraints.md b/gcc/config/bpf/constraints.md
new file mode 100644 (file)
index 0000000..f27b785
--- /dev/null
@@ -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"))
+
diff --git a/gcc/config/bpf/predicates.md b/gcc/config/bpf/predicates.md
new file mode 100644 (file)
index 0000000..9ba0e78
--- /dev/null
@@ -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"))
+
diff --git a/gcc/config/bpf/t-bpf b/gcc/config/bpf/t-bpf
new file mode 100644 (file)
index 0000000..e69de29
index a922f5ca77a63498cc609f46245e7ec97e3cc510..64fccfe9b87a1389ad4db2585e72b10e5195cc76 100644 (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
 
index bfcd76e47bdddcd91300baa7356eee7cc94df18c..7bcdfcbca15715a7844ad2f85e7e29cde4d10faf 100644 (file)
@@ -802,6 +802,10 @@ Objective-C and Objective-C++ Dialects}.
 -msmall-text  -mlarge-text @gol
 -mmemory-latency=@var{time}}
 
+@emph{eBPF Options}
+@gccoptlist{-mbig-endian -mlittle-endian -mkernel=@var{version}
+-mframe-limit=@var{bytes}}
+
 @emph{FR30 Options}
 @gccoptlist{-msmall-model  -mno-lsim}
 
@@ -15650,6 +15654,7 @@ platform.
 * C-SKY Options::
 * Darwin Options::
 * DEC Alpha Options::
+* eBPF Options::
 * FR30 Options::
 * FT32 Options::
 * FRV Options::
@@ -19771,6 +19776,38 @@ Note that L3 is only valid for EV5.
 @end table
 @end table
 
+@node eBPF Options
+@subsection eBPF Options
+@cindex eBPF Options
+
+@table @gcctabopt
+@item -mframe-limit=@var{bytes}
+This specifies the hard limit for frame sizes, in bytes.  Currently,
+the value that can be specified should be less than or equal to
+@samp{32767}.  Defaults to whatever limit is imposed by the version of
+the Linux kernel targeted.
+
+@item -mkernel=@var{version}
+@opindex mkernel
+This specifies the minimum version of the kernel that will run the
+compiled program.  GCC uses this version to determine which
+instructions to use, what kernel helpers to allow, etc.  Currently,
+@var{version} can be one of @samp{4.0}, @samp{4.1}, @samp{4.2},
+@samp{4.3}, @samp{4.4}, @samp{4.5}, @samp{4.6}, @samp{4.7},
+@samp{4.8}, @samp{4.9}, @samp{4.10}, @samp{4.11}, @samp{4.12},
+@samp{4.13}, @samp{4.14}, @samp{4.15}, @samp{4.16}, @samp{4.17},
+@samp{4.18}, @samp{4.19}, @samp{4.20}, @samp{5.0}, @samp{5.1},
+@samp{5.2}, @samp{latest} and @samp{native}.
+
+@item -mbig-endian
+@opindex mbig-endian
+Generate code for a big-endian target.
+
+@item -mlittle-endian
+@opindex mlittle-endian
+Generate code for a little-endian target.  This is the default.
+@end table
+
 @node FR30 Options
 @subsection FR30 Options
 @cindex FR30 Options
index 9533da6e8190699e3ed15bd2665fa0c7e4726996..faa487f51cd3263668099cc497e42dbf1052ee12 100644 (file)
@@ -1,3 +1,218 @@
+2019-09-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       * gcc.dg/builtins-config.h: eBPF doesn't support C99 standard
+       functions.
+       * gcc.c-torture/compile/20101217-1.c: Add a function prototype for
+       printf.
+       * gcc.c-torture/compile/20000211-1.c: Skip if target bpf-*-*.
+       * gcc.c-torture/compile/poor.c: Likewise.
+       * gcc.c-torture/compile/pr25311.c: Likewise.
+       * gcc.c-torture/compile/pr39928-1.c: Likewise.
+       * gcc.c-torture/compile/pr70061.c: Likewise.
+       * gcc.c-torture/compile/920501-7.c: Likewise.
+       * gcc.c-torture/compile/20000403-1.c: Likewise.
+       * gcc.c-torture/compile/20001226-1.c: Likewise.
+       * gcc.c-torture/compile/20030903-1.c: Likewise.
+       * gcc.c-torture/compile/20031125-1.c: Likewise.
+       * gcc.c-torture/compile/20040101-1.c: Likewise.
+       * gcc.c-torture/compile/20040317-2.c: Likewise.
+       * gcc.c-torture/compile/20040726-1.c: Likewise.
+       * gcc.c-torture/compile/20051216-1.c: Likewise.
+       * gcc.c-torture/compile/900313-1.c: Likewise.
+       * gcc.c-torture/compile/920625-1.c: Likewise.
+       * gcc.c-torture/compile/930421-1.c: Likewise.
+       * gcc.c-torture/compile/930623-1.c: Likewise.
+       * gcc.c-torture/compile/961004-1.c: Likewise.
+       * gcc.c-torture/compile/980504-1.c: Likewise.
+       * gcc.c-torture/compile/980816-1.c: Likewise.
+       * gcc.c-torture/compile/990625-1.c: Likewise.
+       * gcc.c-torture/compile/DFcmp.c: Likewise.
+       * gcc.c-torture/compile/HIcmp.c: Likewise.
+       * gcc.c-torture/compile/HIset.c: Likewise.
+       * gcc.c-torture/compile/QIcmp.c: Likewise.
+       * gcc.c-torture/compile/QIset.c: Likewise.
+       * gcc.c-torture/compile/SFset.c: Likewise.
+       * gcc.c-torture/compile/SIcmp.c: Likewise.
+       * gcc.c-torture/compile/SIset.c: Likewise.
+       * gcc.c-torture/compile/UHIcmp.c: Likewise.
+       * gcc.c-torture/compile/UQIcmp.c: Likewise.
+       * gcc.c-torture/compile/USIcmp.c: Likewise.
+       * gcc.c-torture/compile/consec.c: Likewise.
+       * gcc.c-torture/compile/limits-fndefn.c: Likewise.
+       * gcc.c-torture/compile/lll.c: Likewise.
+       * gcc.c-torture/compile/parms.c: Likewise.
+       * gcc.c-torture/compile/pass.c: Likewise.
+       * gcc.c-torture/compile/pp.c: Likewise.
+       * gcc.c-torture/compile/pr32399.c: Likewise.
+       * gcc.c-torture/compile/pr34091.c: Likewise.
+       * gcc.c-torture/compile/pr34688.c: Likewise.
+       * gcc.c-torture/compile/pr37258.c: Likewise.
+       * gcc.c-torture/compile/pr37327.c: Likewise.
+       * gcc.c-torture/compile/pr37381.c: Likewise.
+       * gcc.c-torture/compile/pr37669-2.c: Likewise.
+       * gcc.c-torture/compile/pr37669.c: Likewise.
+       * gcc.c-torture/compile/pr37742-3.c: Likewise.
+       * gcc.c-torture/compile/pr44063.c: Likewise.
+       * gcc.c-torture/compile/pr48596.c: Likewise.
+       * gcc.c-torture/compile/pr51856.c: Likewise.
+       * gcc.c-torture/compile/pr54428.c: Likewise.
+       * gcc.c-torture/compile/pr54713-1.c: Likewise.
+       * gcc.c-torture/compile/pr54713-2.c: Likewise.
+       * gcc.c-torture/compile/pr54713-3.c: Likewise.
+       * gcc.c-torture/compile/pr55921.c: Likewise.
+       * gcc.c-torture/compile/pr70240.c: Likewise.
+       * gcc.c-torture/compile/pr70355.c: Likewise.
+       * gcc.c-torture/compile/pr82052.c: Likewise.
+       * gcc.c-torture/compile/pr83487.c: Likewise.
+       * gcc.c-torture/compile/pr86122.c: Likewise.
+       * gcc.c-torture/compile/pret-arg.c: Likewise.
+       * gcc.c-torture/compile/regs-arg-size.c: Likewise.
+       * gcc.c-torture/compile/structret.c: Likewise.
+       * gcc.c-torture/compile/uuarg.c: Likewise.
+       * gcc.dg/20001009-1.c: Likewise.
+       * gcc.dg/20020418-1.c: Likewise.
+       * gcc.dg/20020426-2.c: Likewise.
+       * gcc.dg/20020430-1.c: Likewise.
+       * gcc.dg/20040306-1.c: Likewise.
+       * gcc.dg/20040622-2.c: Likewise.
+       * gcc.dg/20050603-2.c: Likewise.
+       * gcc.dg/20050629-1.c: Likewise.
+       * gcc.dg/20061026.c: Likewise.
+       * gcc.dg/Warray-bounds-3.c: Likewise.
+       * gcc.dg/Warray-bounds-30.c: Likewise.
+       * gcc.dg/Wframe-larger-than-2.c: Likewise.
+       * gcc.dg/Wframe-larger-than.c: Likewise.
+       * gcc.dg/Wrestrict-11.c: Likewise.
+       * gcc.c-torture/compile/20000804-1.c: Likewise.
+
+2019-09-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       * lib/target-supports.exp (check_effective_target_trampolines):
+       Adapt to eBPF.
+       (check_effective_target_indirect_jumps): Likewise.
+       (check_effective_target_nonlocal_goto): Likewise.
+       (check_effective_target_global_constructor): Likewise.
+       (check_effective_target_return_address): Likewise.
+
+2019-09-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       * gcc.target/bpf/bpf.exp: New file.
+       * gcc.target/bpf/builtin-load.c: Likewise.
+       * cc.target/bpf/constant-calls.c: Likewise.
+       * gcc.target/bpf/diag-funargs.c: Likewise.
+       * gcc.target/bpf/diag-funargs-2.c: Likewise.
+       * gcc.target/bpf/diag-funargs-3.c: Likewise.
+       * gcc.target/bpf/diag-indcalls.c: Likewise.
+       * gcc.target/bpf/helper-bind.c: Likewise.
+       * cc.target/bpf/helper-bpf-redirect.c: Likewise.
+       * gcc.target/bpf/helper-clone-redirect.c: Likewise.
+       * gcc.target/bpf/helper-csum-diff.c: Likewise.
+       * gcc.target/bpf/helper-csum-update.c: Likewise.
+       * gcc.target/bpf/helper-current-task-under-cgroup.c: Likewise.
+       * gcc.target/bpf/helper-fib-lookup.c: Likewise.
+       * gcc.target/bpf/helper-get-cgroup-classid.c: Likewise.
+       * gcc.target/bpf/helper-get-current-cgroup-id.c: Likewise.
+       * gcc.target/bpf/helper-get-current-comm.c: Likewise.
+       * gcc.target/bpf/helper-get-current-pid-tgid.c: Likewise.
+       * gcc.target/bpf/helper-get-current-task.c: Likewise.
+       * gcc.target/bpf/helper-get-current-uid-gid.c: Likewise.
+       * gcc.target/bpf/helper-get-hash-recalc.c: Likewise.
+       * gcc.target/bpf/helper-get-listener-sock.c: Likewise.
+       * gcc.target/bpf/helper-get-local-storage.c: Likewise.
+       * gcc.target/bpf/helper-get-numa-node-id.c: Likewise.
+       * gcc.target/bpf/helper-get-prandom-u32.c: Likewise.
+       * gcc.target/bpf/helper-get-route-realm.c: Likewise.
+       * gcc.target/bpf/helper-get-smp-processor-id.c: Likewise.
+       * gcc.target/bpf/helper-get-socket-cookie.c: Likewise.
+       * gcc.target/bpf/helper-get-socket-uid.c: Likewise.
+       * gcc.target/bpf/helper-getsockopt.c: Likewise.
+       * gcc.target/bpf/helper-get-stack.c: Likewise.
+       * gcc.target/bpf/helper-get-stackid.c: Likewise.
+       * gcc.target/bpf/helper-ktime-get-ns.c: Likewise.
+       * gcc.target/bpf/helper-l3-csum-replace.c: Likewise.
+       * gcc.target/bpf/helper-l4-csum-replace.c: Likewise.
+       * gcc.target/bpf/helper-lwt-push-encap.c: Likewise.
+       * gcc.target/bpf/helper-lwt-seg6-action.c: Likewise.
+       * gcc.target/bpf/helper-lwt-seg6-adjust-srh.c: Likewise.
+       * gcc.target/bpf/helper-lwt-seg6-store-bytes.c: Likewise.
+       * gcc.target/bpf/helper-map-delete-elem.c: Likewise.
+       * gcc.target/bpf/helper-map-lookup-elem.c: Likewise.
+       * gcc.target/bpf/helper-map-peek-elem.c: Likewise.
+       * gcc.target/bpf/helper-map-pop-elem.c: Likewise.
+       * gcc.target/bpf/helper-map-push-elem.c: Likewise.
+       * gcc.target/bpf/helper-map-update-elem.c: Likewise.
+       * gcc.target/bpf/helper-msg-apply-bytes.c: Likewise.
+       * gcc.target/bpf/helper-msg-cork-bytes.c: Likewise.
+       * gcc.target/bpf/helper-msg-pop-data.c: Likewise.
+       * gcc.target/bpf/helper-msg-pull-data.c: Likewise.
+       * gcc.target/bpf/helper-msg-push-data.c: Likewise.
+       * gcc.target/bpf/helper-msg-redirect-hash.c: Likewise.
+       * gcc.target/bpf/helper-msg-redirect-map.c: Likewise.
+       * gcc.target/bpf/helper-override-return.c: Likewise.
+       * gcc.target/bpf/helper-perf-event-output.c: Likewise.
+       * gcc.target/bpf/helper-perf-event-read.c: Likewise.
+       * gcc.target/bpf/helper-perf-event-read-value.c: Likewise.
+       * gcc.target/bpf/helper-perf-prog-read-value.c: Likewise.
+       * gcc.target/bpf/helper-probe-read.c: Likewise.
+       * gcc.target/bpf/helper-probe-read-str.c: Likewise.
+       * gcc.target/bpf/helper-probe-write-user.c: Likewise.
+       * gcc.target/bpf/helper-rc-keydown.c: Likewise.
+       * gcc.target/bpf/helper-rc-pointer-rel.c: Likewise.
+       * gcc.target/bpf/helper-rc-repeat.c: Likewise.
+       * gcc.target/bpf/helper-redirect-map.c: Likewise.
+       * gcc.target/bpf/helper-set-hash.c: Likewise.
+       * gcc.target/bpf/helper-set-hash-invalid.c: Likewise.
+       * gcc.target/bpf/helper-setsockopt.c: Likewise.
+       * gcc.target/bpf/helper-skb-adjust-room.c: Likewise.
+       * gcc.target/bpf/helper-skb-cgroup-id.c: Likewise.
+       * gcc.target/bpf/helper-skb-change-head.c: Likewise.
+       * gcc.target/bpf/helper-skb-change-proto.c: Likewise.
+       * gcc.target/bpf/helper-skb-change-tail.c: Likewise.
+       * gcc.target/bpf/helper-skb-change-type.c: Likewise.
+       * gcc.target/bpf/helper-skb-ecn-set-ce.c: Likewise.
+       * gcc.target/bpf/helper-skb-get-tunnel-key.c: Likewise.
+       * gcc.target/bpf/helper-skb-get-tunnel-opt.c: Likewise.
+       * gcc.target/bpf/helper-skb-get-xfrm-state.c: Likewise.
+       * gcc.target/bpf/helper-skb-load-bytes.c: Likewise.
+       * gcc.target/bpf/helper-skb-load-bytes-relative.c: Likewise.
+       * gcc.target/bpf/helper-skb-pull-data.c: Likewise.
+       * gcc.target/bpf/helper-skb-set-tunnel-key.c: Likewise.
+       * gcc.target/bpf/helper-skb-set-tunnel-opt.c: Likewise.
+       * gcc.target/bpf/helper-skb-store-bytes.c: Likewise.
+       * gcc.target/bpf/helper-skb-under-cgroup.c: Likewise.
+       * gcc.target/bpf/helper-skb-vlan-pop.c: Likewise.
+       * gcc.target/bpf/helper-skb-vlan-push.c: Likewise.
+       * gcc.target/bpf/helper-skc-lookup-tcp.c: Likewise.
+       * gcc.target/bpf/helper-sk-fullsock.c: Likewise.
+       * gcc.target/bpf/helper-sk-lookup-tcp.c: Likewise.
+       * gcc.target/bpf/helper-sk-lookup-upd.c: Likewise.
+       * gcc.target/bpf/helper-sk-redirect-hash.c: Likewise.
+       * gcc.target/bpf/helper-sk-redirect-map.c: Likewise.
+       * gcc.target/bpf/helper-sk-release.c: Likewise.
+       * gcc.target/bpf/helper-sk-select-reuseport.c: Likewise.
+       * gcc.target/bpf/helper-sk-storage-delete.c: Likewise.
+       * gcc.target/bpf/helper-sk-storage-get.c: Likewise.
+       * gcc.target/bpf/helper-sock-hash-update.c: Likewise.
+       * gcc.target/bpf/helper-sock-map-update.c: Likewise.
+       * gcc.target/bpf/helper-sock-ops-cb-flags-set.c: Likewise.
+       * gcc.target/bpf/helper-spin-lock.c: Likewise.
+       * gcc.target/bpf/helper-spin-unlock.c: Likewise.
+       * gcc.target/bpf/helper-strtol.c: Likewise.
+       * gcc.target/bpf/helper-strtoul.c: Likewise.
+       * gcc.target/bpf/helper-sysctl-get-current-value.c: Likewise.
+       * gcc.target/bpf/helper-sysctl-get-name.c: Likewise.
+       * gcc.target/bpf/helper-sysctl-get-new-value.c: Likewise.
+       * gcc.target/bpf/helper-sysctl-set-new-value.c: Likewise.
+       * gcc.target/bpf/helper-tail-call.c: Likewise.
+       * gcc.target/bpf/helper-tcp-check-syncookie.c: Likewise.
+       * gcc.target/bpf/helper-tcp-sock.c: Likewise.
+       * gcc.target/bpf/helper-trace-printk.c: Likewise.
+       * gcc.target/bpf/helper-xdp-adjust-head.c: Likewise.
+       * gcc.target/bpf/helper-xdp-adjust-meta.c: Likewise.
+       * gcc.target/bpf/helper-xdp-adjust-tail.c: Likewise.
+       * gcc.target/bpf/skb-ancestor-cgroup-id.c: Likewise.
+       * gcc.target/bpf/sync-fetch-and-add.c: Likewise.
+
 2019-09-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
        * lib/target-supports.exp (check_effective_target_indirect_calls):
index 7a7c8c0cb2036b81516c9675e403e0477749552f..b83d6a4052003cf7caf866bf63c86ab18b2317f7 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef __SIZE_TYPE__ size_t;
 typedef unsigned char Bufbyte;
 typedef int Bytecount;
index 27345b56fef9b27f3dbe3c7f32ce608b7bc5f80e..cb56028fb8b7dd4521dbd634f27f68f220172bbd 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 struct utsname {
        char    sysname[32 ];    
        char    version[32 ];    
index 550669b53a3d1a3283f90d4cbd029a096c9060c7..95bb0fafd7044f90a12dec16573e3b99d04a2616 100644 (file)
@@ -5,6 +5,7 @@
 /* { dg-skip-if "No 64-bit registers" { m32c-*-* } } */
 /* { dg-skip-if "Not enough 64-bit registers" { pdp11-*-* } { "-O0" } { "" } } */
 /* { dg-xfail-if "Inconsistent constraint on asm" { csky-*-* } { "-O0" } { "" } } */
+/* { dg-xfail-if "Inconsistent constraint on asm" { bpf-*-* } { "-O0" } { "" } } */
 /* { dg-xfail-if "" { h8300-*-* } } */
 /* { dg-require-stack-size "99*4+16" } */
 
index 073ac6a784d36357fc6aa46758a64bd8e79ac255..234cdbf1b14f6dff6acc2b3572182402ac4a77d2 100644 (file)
@@ -2,6 +2,7 @@
 /* { dg-skip-if "too much code for avr" { "avr-*-*" } } */
 /* { dg-skip-if "too much code for pdp11" { "pdp11-*-*" } } */
 /* { dg-skip-if "" { m32c-*-* } } */
+/* { dg-skip-if "jumps too far for eBPF" { bpf-*-* } } */
 /* { dg-timeout-factor 4.0 } */
 
 /* This testcase exposed two branch shortening bugs on powerpc.  */
index fa4d30db6c0f75f0e51cd0130f5c759f01a47a86..116b0923721e182fbfef1aa0be579a70404acd24 100644 (file)
@@ -1,6 +1,8 @@
 /* Derived from PR optimization/11700.  */
 /* The compiler used to ICE during reload for m68k targets.  */
 
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
 void check_complex (__complex__ double, __complex__ double,
                     __complex__ double, __complex__ int);
 void check_float (double, double, double, int);
index d3e92679c8b35b4678805e31e8ab0a3d46ba15aa..bec6c9372a8af2f89e838f3df5125631e8056c04 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 short *_offsetTable;
 /* This tests to make sure PRE splits the entry block ->block 0 edge
    when there are multiple block 0 predecessors.
index 5c2688ad830f6681a3046907216e46ebe66af6bf..6027cb53fb4cb219b69cef201c34e0f64da5cece 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-skip-if "not enough registers" { pdp11-*-* } } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 typedef unsigned short uint16_t;
 typedef unsigned int uint32_t;
index 3c8ee2b8ec5ca428f48f4168512abad3166df4fa..3a1fbde2969df9c17b0ff9b8a697fe6a4eae6bcf 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef struct _ScaleRec *ScaleWidget;
 typedef struct
 {
index e53ccd655bbaab34049e9ca72f954d4a0cefa03c..aea43a56f34de4bb06921a4978eac65ed48a14f6 100644 (file)
@@ -1,4 +1,6 @@
 /* PR rtl-optimization/16643 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 void foo (int a, int b, int c, int d, int e, int *f)
 {
   if (a == 0)
index ed6ac723069cbc577f07660d7f3bad7fc3acc631..55751ec8ab29a053aed48994c1f0d9458c0fb492 100644 (file)
@@ -1,4 +1,5 @@
 /* PR rtl-optimization/25432 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 void *malloc (__SIZE_TYPE__);
 void *realloc (void *, __SIZE_TYPE__);
index c4eef0ed464509430d8e2bd31ffd1ad9660ab36f..46bdcf5e347e09d5aa1b961369d0c9d27de6a8d8 100644 (file)
@@ -1,5 +1,7 @@
 /* Testcase provided by HUAWEI.  */
-#include <stdio.h>
+
+extern int printf (const char * __format, ...);
+
 int main()
 {
         int cur_k;
index 2bac5814a7b90a405fc82bf6b70819cf7bd8d88f..12252b4b22903a67f51782607cd2d9764afeca82 100644 (file)
@@ -1,4 +1,6 @@
 /* { dg-require-effective-target alloca } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 main ()
 {
   char *a;
index 2af15e3b7ec4e84ded179bf9d4cf608231e5f796..0fac5f3495f59fca5821fa24f5349dd0e243fefe 100644 (file)
@@ -1,3 +1,4 @@
 /* { dg-require-effective-target label_values } */
+/* { dg-skip-if "no support for indirect jumps" { bpf-*-* } } */
 
 x(){if(&&e-&&b<0)x();b:goto*&&b;e:;}
index 720d43fd42fa20863ce2440636c0ec794eb5c061..759a356b5b75cfc573b0daaa4c0e5839e168c64e 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef unsigned long int unsigned_word;
 typedef signed long int signed_word;
 typedef unsigned_word word;
index 01b465f7fecbf19a4fc6307a6ab527ec3347602d..9e16fe17dd957e27a5de55628f40bf05ef490634 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 double q(double);
 
 f (int **x, int *r, int *s, int a, int b, int c, int d)
index 022ad01804edb3770266f2ffb641a291c813873b..dd45bbccc38d17f8676defca94356f87098fc4da 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "no __builtin_apply in eBPF" { bpf-*-* } } */
 
 g (a, b) {}
 
index 6407b625d668866331eb791da98492a4ef172ba1..cf47f60d5eaf44bd6099ec808d32151e087a4732 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 void
 f1 (o1, o2, o3, i, j, k)
      long long *o1, *o2, *o3;
index 7b757ccd2e8c4fcb700b11ee188b036f90000d83..6e043a7af193a4e54dd8bd065dedc52038d5d018 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef struct _geom_elem {
   double        coeffs[6];
 } pGeomDefRec, *pGeomDefPtr;
index a79100fab57a103ecd6fbe6f90351b85e15bc17e..5bd83b17063b7e2e6fda939e623881b171c3d6ea 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef __SIZE_TYPE__ size_t;
 typedef void *XtPointer;
 
index 97a2331c7a5dc0f913c9b19f25a0a9ce60d001f3..befff06579e4d71a9c0f5b3b62789487374a9395 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "no string.h in eBPF" { bpf-*-* } } */
+
 #define __USE_STRING_INLINES
 #include <string.h>
 
index 3bb253476d7317fa0f4a27259b7bd83ec7ea0053..808874de1a88dc38c5e48f2d2293910a6a1fcfc4 100644 (file)
@@ -1,4 +1,6 @@
 /* { dg-require-effective-target int32plus } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define type double
 
 type glob0, glob1;
index 77b47886ed1ee67c2bf76371ab9762e07d126bb6..6e68271a00946067860503ff0b58725ee4deb289 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define type short
 
 type glob0, glob1;
index 163cb7cbe320a61ddec25692238dbb7413dff260..a0d426c2c077eba3e910aa457ae890953f659897 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define E0 ((type *)10000000)
 #define reg0 r0
 #define indreg0 (*p0)
index c5161646f2cb276b5a6e143a90f3e2a16a404909..a4dba2487e42c57b5151089e566742d95d4aa09f 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define type signed char
 
 type glob0, glob1;
index 212609dc864a6d75ea2bc9c636f73efd3829a6ff..e2fde2bda7e1a91be93742ac6f53252412e7dd68 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define E0 ((type *)10000000)
 #define reg0 r0
 #define indreg0 (*p0)
index dc7f48dd2dd9e61ef4311516c69bde3bc9d07481..a7efecf9717803b847c433b5d97c989a04c7eabb 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-require-effective-target int32plus } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 #define E0 ((type *)10000000)
 #define reg0 r0
index 4a9e0d57fd7d72641e02b4d76c946de5acae8645..ce1281b60938a5e402b20b91cd8a9c3ef9bbea33 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define type int
 
 type glob0, glob1;
index 5fb93579f4bfc5be8a8be7fa0313a057b88ba1c9..b200a264b95490d04fe7d2498fb275f44f845670 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define E0 ((type *)10000000)
 #define reg0 r0
 #define indreg0 (*p0)
index 529e3a33fd35199141d1bf35a0a8c46af5419bc1..b0029d23ea4f4120dbe38e43f23ebb2159e75de4 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define type unsigned short
 
 type glob0, glob1;
index 3e9cdebc903e7652f82b11f9d9f83b78e7c45b83..e28d13b03abc7d3cb595cf3a06fcd261bf137de8 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define type unsigned char
 
 type glob0, glob1;
index 69788a45b2e97b6ead2e5fa7c05ac26429c653a8..27e5503bd4d4afe4f378ffc991d9a74c290bc34c 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 #define type unsigned int
 
 type glob0, glob1;
index 01fa25b009b8bc1761fb9d74214c89635437cc46..b8c376d707696a9c3cd3a842f144fc134acb359f 100644 (file)
@@ -1,4 +1,6 @@
 /* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 int glob;
 
 conseq (a, b, c, d)
index 0bd8f6af99581bea328d9c8a50d8bb1651460305..53204735493860c3f66cc6d6d81a7bff933c53f2 100644 (file)
@@ -1,5 +1,6 @@
 /* { dg-skip-if "too complex for avr" { avr-*-* } } */
 /* { dg-skip-if "ptxas times out" { nvptx-*-* } } */
+/* { dg-skip-if "no chance for bpf" { bpf-*-* } } */
 /* { dg-timeout-factor 4.0 } */
 #define LIM1(x) x##0, x##1, x##2, x##3, x##4, x##5, x##6, x##7, x##8, x##9,
 #define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \
index dee9dc37d1599ede0b07a6e220232f3b72b34fc2..ea09c871c6b2e990ed1734d4efee4d1e9a4896f4 100644 (file)
@@ -1,3 +1,4 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 byte_match_count2 (buf, n, xm, m1, m2, m3, m4)
      unsigned *buf;
index 8205a9c14547dcbdd8cee4005e4d2b58ca6f4a0c..1bfc93d2abb960f5d880c0e4ab49927fb2d65761 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-require-effective-target alloca } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 #define alloca __builtin_alloca
 
 x (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, x, y)
index 4e028393feb6b0c28e11d674362c58c519052d79..529a01dac85cd4309ed08604b36064fcd6311950 100644 (file)
@@ -1,4 +1,6 @@
 /* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 int
 foo (a, b, c)
 {
index 66d584aff432321299996b6fa1a44197ed71ca47..20287ef23548626b01c490e7a54f41b6da2295ec 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
 typedef struct
 {
        char    c[510];
index 7d38d53de0f56f2484de09580ce6c2f126b61668..c1e09eab4077bee0ba6d43589b0620e1674a8c5e 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 foo (a, b, c, d, e, i0, f, i1)
      double a, b, c, d, e, f;
      int i0, i1;
index 26c5bc37b831da305cf50bb8eef25a8a04ea4578..43ef3fd9523a1e766f5dccb39f23366d750a0dd4 100644 (file)
@@ -1,3 +1,4 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 struct w
 {
index cc2b1b1898436460f6d83831147b2b4b8f3714a5..b29dbd7986a3ae7f7341ac120711bdbda3be7530 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 void f(unsigned char *src, unsigned char *dst, int num, unsigned char *pos, unsigned char *diffuse, int hasdiffuse, unsigned char *specular, int hasspecular) {
     int i;
 
index 0b8549132e6dbaa76fa468a2d3c136fe34f11116..a623a383fd0720c942a57cf3536c242431c17453 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef unsigned int GLenum;
 typedef unsigned char GLboolean;
 typedef int GLint;
index 60e0f3c9f1556a99690cf973bc31717ba2cf3189..ec890cb8f15bf595c1a46a0491cf01ce69df884a 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef __SIZE_TYPE__ size_t;
          typedef struct {
         }
index 286f2fc4427ae5702417acbdf5a063dedb508742..41801781e3acdacd1a6358299797acff799803c4 100644 (file)
@@ -1,4 +1,6 @@
 /* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef signed char int8_t;
 typedef short int int16_t;
 typedef int int32_t;
index 79946b7522de952cda9c427f1dab4bc56f77613f..5ca9d1d45b61c3791b835406e52042a9a641435a 100644 (file)
@@ -1,4 +1,6 @@
 /* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef signed char int8_t;
 typedef short int int16_t;
 typedef int int32_t;
index a2fed66c4eed704ff1f6bc91c04fadeec4e5fe73..d8cd47d329d06d5632ff182c4630b1274f47fdf8 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 extern unsigned int __invalid_size_argument_for_IOC;
 typedef unsigned int __u32;
 struct video_window
index abeae7a2f32fccb7ebcd3ba9d663ae61f22aa0d0..2170dda67f0eec620f047ac504c64a3b1826ffd7 100644 (file)
@@ -1,4 +1,5 @@
 /* PR middle-end/37669 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 #define FMT10 "%d%d%d%d%d%d%d%d%d%d"
 #define FMT100 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10
index a2eafc75cb30b8857046cc0d385a8cf16b5016a1..36e4c39d8ed75b507059cefe55ab5474e559634b 100644 (file)
@@ -1,6 +1,7 @@
 /* This testcase used to fail because a miscompiled execute_fold_all_builtins. */
 /* { dg-options "-fgnu89-inline" } */
 /* { dg-require-effective-target int32plus } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 typedef __SIZE_TYPE__ size_t;
 extern __inline __attribute__ ((__always_inline__)) int __attribute__
index 541bd42ad5d684a4ce40394ef6a6c34f118656ab..9e7b10fb7a33f99a2e97c7988f0ddf96ec519476 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 void matmul_i4 (int * __restrict dest_y,
                const int * __restrict abase,
                const int * __restrict bbase_y,
index 1abb5ccb505dcbc447aca86e1936eca35193ba13..ae6a63b24b8c358b28eee7a37d0ffaeab89de576 100644 (file)
@@ -1,4 +1,6 @@
 /* { dg-options "-msse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
 extern __m128 _mm_sub_ps (__m128 __A, __m128 __B);
 extern __m128 _mm_mul_ps (__m128 __A, __m128 __B);
index 596e1dc991f09c287e4fffa4971ee18698fd1376..32208f610f9bc34308a7debb735847ba3bd246a0 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
 typedef signed char int8_t;
 typedef short int16_t;
 typedef unsigned char uint8_t;
index 382a152413efd7a0135bf604da7002f99b1fe1f4..743bd82e868905d7b4af4a3f6bb4c0d26af4383e 100644 (file)
@@ -1,4 +1,6 @@
 /* PR target/48596  */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 enum { nrrdCenterUnknown, nrrdCenterNode, nrrdCenterCell, nrrdCenterLast };
 typedef struct { int size; int center; }  NrrdAxis;
 typedef struct { int dim; NrrdAxis axis[10]; } Nrrd;
index 6644c7fdc14d932bb03697a0f03ebff8b38dcf3d..823a0bed073c86d6cb07f66f897ea02728c61fb3 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 struct B { int b1; long long b2, b3; int b4; };
 struct C { char c1[40], c2, c3[96]; long long c4[5], c5; char c6[596]; };
 void fn1 (long long), fn2 (char *, int), fn4 (void);
index 84a5dbd82bd7d758009c7ad47bcdac3c6d2e0498..d783337cfdb99af460ac0010573237a6fb68d30e 100644 (file)
@@ -1,4 +1,5 @@
 /* PR c/54428 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 typedef double _Complex C;
 
index f042ea2fc6c39552b7dab3a1215367066abd472f..0d4172a576b6c043c9a1d88df16ce25239aa28e8 100644 (file)
@@ -1,4 +1,5 @@
 /* PR tree-optimization/54713 */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 #ifndef N
 #define N 8
index c3910373111ac1977772e8342f1f600cc6d82677..f7d2364e1973db7139adf8e8b9a588e066f5c63b 100644 (file)
@@ -1,4 +1,5 @@
 /* PR tree-optimization/54713 */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 #define N 16
 #define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
index 6164a5eec0ec057dc81513d40fd9055abb1f9152..76a35b067c51a46a4af8aea7dabd9ee25a83e18a 100644 (file)
@@ -1,4 +1,5 @@
 /* PR tree-optimization/54713 */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 #define N 32
 #define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
index de0635d66ad0dbacfe1a5ab699dfe7b5fbbc68ba..cf9084e33f0c38db89bcede770e3c538c9bf1e75 100644 (file)
@@ -1,5 +1,6 @@
 /* PR tree-optimization/55921 */
 /* { dg-skip-if "Not enough registers" { "pdp11-*-*" } } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 typedef union
 {
index a7ebcfc99f872267199af9cf4ae2cfe3b8891da5..aabfddad43f3653daf31a5e2e92d2a5144d0cc63 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef int v8si __attribute__ ((vector_size (32)));
 
 int
index 830d4ddcc9359353fba09b0f55ae2afecf95aae4..466d3a7c961309d5a8cf46a412910c2a69e3b7a0 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 typedef short v16hi __attribute__ ((vector_size (32)));
 typedef int v8si __attribute__ ((vector_size (32)));
 typedef long long v4di __attribute__ ((vector_size (32)));
index 474942715f8949741ac977ac651101aace342c80..f7114208005bae11bb3321802c6e1eec443bb03e 100644 (file)
@@ -1,5 +1,7 @@
 /* { dg-require-effective-target int128 } */
 /* { dg-additional-options "-g" } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
 
 typedef unsigned __int128 v2ti __attribute__ ((vector_size (32)));
 
index 3763161e35040faaa10b311c9351970dfe030675..09fac5edb1e59d4eaaa532d99cb0eb4ddc43b04a 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
 typedef unsigned char uint8_t;
 typedef unsigned short uint16_t;
 typedef unsigned uint32_t;
index 9effb1eef03950ea7abbed42f415fc70fff7c19b..9de0e17939f8bf14f98100b7ed9b35d91821189d 100644 (file)
@@ -1,4 +1,5 @@
 /* PR middle-end/83487 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 struct __attribute__ ((aligned)) A {};
 struct A a;
index 0a4fd144ae6ee23d3d0d45c10fc2cd6ecc071c6b..1bd467331830fdad95f2bd1692010f743453aa29 100644 (file)
@@ -1,4 +1,5 @@
 /* PR middle-end/86122 */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 _Complex int
 foo (_Complex int x)
index a7fa8562830afacf7cd92006f702fe1e2ab16d1b..d86d135dc4b3151c371c7e010a86f09fdec66549 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 foo (a, b, c, d, e, f, g, h, i, j, xx)
      double xx;
 {
index f5f01116eda757c198ca0b4bbd3d2a8c5425f0f9..77518866d3f623bf7162a3e5ccc440adfc30ef3e 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
 int foo;
 typedef long unsigned int size_t;
 typedef short unsigned int wchar_t;
index 9c705d4c0a229bfa89a6098d76336f675d376c9e..d99eaa630bbc29b93a7610e58235424fb1cda5cd 100644 (file)
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 struct foo
 {
   int a, b, c, d;
index 930dd8ab5f61a148e743427b448db303f9b21470..875c7c3b50f2c81b98c92652cc11dd158ce8bcad 100644 (file)
@@ -1,4 +1,6 @@
 /* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
 foo (a, b, c, d, e, f, g, h, i)
 {
   return foo () + i;
index 1a5567779b508c512733cdd1556427762975f54d..580e4b4d307d4e7fdbb910223f11a9d6aa6fc1b6 100644 (file)
@@ -1,5 +1,6 @@
 /* { dg-do compile { target fpic } } */
 /* { dg-options "-O2 -fpic" } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 extern void foo (void *a, double x, double y);
 void
index 7314ec000ef2aedf85c33a6d12a343cbd501590c..456967fdd363209198117db4aa6c9f692733f330 100644 (file)
@@ -2,6 +2,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
 /* { dg-options "-O2 -msse -ffast-math" { target i?86-*-* x86_64-*-* } } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 void bar (float *a, float *b);
 
index 9ad7a54f6016e78aaf301653c755a00e0ff061ce..96517f7b840552af24fc13527ae79c5dc1407168 100644 (file)
@@ -3,6 +3,7 @@
 /* { dg-do run } */
 /* { dg-options "-O2" } */
 /* { dg-options "-O2 -frename-registers -fomit-frame-pointer -fPIC -mtune=i686" { target { { i?86-*-* x86_64-*-* } && { ia32 && fpic } } } } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 extern void exit (int);
 
index 63915a24b1792c302d86f80fec2cf9bc581820d2..f48bb672aaf64e2fdf5ea4e45cb9b51159bdb3c3 100644 (file)
@@ -6,6 +6,7 @@
 
 /* { dg-do compile { target fpic } } */
 /* { dg-options "-O2 -frename-registers -fpic" } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 typedef unsigned long XID;
 typedef XID Window;
index 903d20ac2563a4f63a8bd0fbc7682520a56c264f..8cac8697d99068610cbc1b435eb2012e9306fe2b 100644 (file)
@@ -2,7 +2,7 @@
 
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
-
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 typedef struct test
 {
index 0be320fa4e240b6b4743448b97a6d3e36a9343d2..e62ec36d43a49f53f06b973439c475812f00633f 100644 (file)
@@ -1,5 +1,6 @@
 /* { dg-do link } */
 /* { dg-require-effective-target ptr32plus } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 /* This validates codegen for [r1+32760] on Darwin. */
 void f(char x[32688], double *y, double *z) __attribute__((noinline));
 void f(char x[32688], double *y, double *z) {}
index 8c8e58e1b4d60a363b33bdbb6284a01c5f83fbea..a135e3ea1a09f54c9b1e8b06440c1723ff4fd8ff 100644 (file)
@@ -1,5 +1,6 @@
 /* { dg-do run } */
 /* { dg-options "-O2" } */
+/* { dg-skip-if "no stdlib.h in eBPF" { bpf-*-* } } */
 #include <stdlib.h>
 struct s {
   unsigned short f: 16;
index 0dd47f7024b68d3d216c67b2f02b43ce95874e01..99d9ce823b0a6d4cd0796f5782248924e7129537 100644 (file)
@@ -1,5 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -w" } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 /* This file was automatically reduced from tree-ssa-operands.c.  It
    contains many warnings, but it exposes a copy propagation bug that
index 741ea2eb3b860b83ed06941a5bba32b1fb3857bc..fa8069ce4cfa23f5448c003314e9b4efafcd4f91 100644 (file)
@@ -1,5 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O1" } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 /* This testcase failed on s390.  The frame size for function f will be
    exactly 32768 bytes.  The back end has to recognize that this is to
index 773f4633dc799329c79b02f50257e0ffa2f90b24..f119502f0250eda4cf32f5173c8c0c8054f103d6 100644 (file)
@@ -1,5 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -Warray-bounds" } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 /* based on PR 31227 */
 
 typedef __SIZE_TYPE__ size_t;
index ac7e9a6e8fbe6aff977c38f84f1a173e5cd41b36..b99656821017626fe1d03fcaec8f7689f715c82e 100644 (file)
@@ -1,7 +1,8 @@
 /* PR tree-optimization/84047 - missing -Warray-bounds on an out-of-bounds
    index into an array
    { dg-do compile }
-   { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" } */
+   { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" }
+   { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 #include "range.h"
 
index 1a5402f812035ff69b7c75f4e8a9603f88a8a3fe..d7068d04aef618b600837f8fb8f7da30b889bf8d 100644 (file)
@@ -1,6 +1,7 @@
 /* Exercise -Wframe-larger-than= with a byte-size suffix.
    { dg-do compile }
-   { dg-options "-O -Wframe-larger-than=1KB" } */
+   { dg-options "-O -Wframe-larger-than=1KB" }
+   { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 extern void f (void*, ...);
 
index fab0adf37eed1107948e675dfc4d8d7403d6467a..8a40cf36df86a302c156f12f29c2b744b7835ce6 100644 (file)
@@ -4,6 +4,7 @@
 
 /* { dg-do compile } */
 /* { dg-options "-Wframe-larger-than=2048" } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
 
 extern void func(char *);
 
index 7b4b5aa25279d27594d934698f2190a75ab0180e..07b9cddad4bf52cc3bd593661407799cb05ddae6 100644 (file)
@@ -3,7 +3,8 @@
    that calls to strncpy involving multidimensional arrays of structs don't
    trigger false positive -Wrestrict warnings.
    { dg-do compile }
-   { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } */
+   { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" }
+   { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
 
 typedef __SIZE_TYPE__ size_t;
 
index f00e91a750f0b235d54e6be9f8f7f6a3d889d9fa..5e27c1deb33eda53c8e2dd1f44f09ef2e99adf8d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2009, 2011, 2012
+/* Copyright (C) 2003, 2004, 2005, 2006, 2009, 2011, 2012, 2019
    Free Software Foundation.
 
    Define macros useful in tests for bulitin functions.  */
@@ -20,6 +20,8 @@
 /* FreeBSD up to version 8 lacks support for cexp and friends.  */
 #elif defined(__vxworks)
 /* VxWorks doesn't have a full C99 time.  (cabs is missing, for example.)  */
+#elif defined (__BPF__)
+/* No chance for eBPF to support C99 functions.  */
 #elif defined(_WIN32) && !defined(__CYGWIN__)
 /* Windows doesn't have the entire C99 runtime.  */
 #elif (defined(__APPLE__) && defined(__ppc__) \
diff --git a/gcc/testsuite/gcc.target/bpf/bpf.exp b/gcc/testsuite/gcc.target/bpf/bpf.exp
new file mode 100644 (file)
index 0000000..e5c8cfc
--- /dev/null
@@ -0,0 +1,41 @@
+# Copyright (C) 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an eBPF target.
+if ![istarget bpf-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+       "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/bpf/builtin-load.c b/gcc/testsuite/gcc.target/bpf/builtin-load.c
new file mode 100644 (file)
index 0000000..0f93d91
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -std=gnu99" } */
+
+void foo ()
+{
+  long long ll, off;
+
+  /* Indirect.  */
+  ll = __builtin_bpf_load_byte (off);
+  ll = __builtin_bpf_load_half (off);
+  ll = __builtin_bpf_load_word (off);
+
+  /* Absolute.  */
+  ll = __builtin_bpf_load_byte (0);
+  ll = __builtin_bpf_load_half (4);
+  ll = __builtin_bpf_load_word (8);
+}
+
+/* { dg-final { scan-assembler "ldindb\t%r.,0.*ldindh\t%r.,0.*ldindw\t%r.,0" } } */
+/* { dg-final { scan-assembler "ldabsb\t0.*ldabsh\t4.*ldabsw\t8" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/constant-calls.c b/gcc/testsuite/gcc.target/bpf/constant-calls.c
new file mode 100644 (file)
index 0000000..84612a9
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-xfail-if "" { bpf-*-* } } */
+
+typedef void  *(*T)(void);
+f1 ()
+{
+  ((T) 0)();
+}
+f2 ()
+{
+  ((T) 1000)();
+}
+f3 ()
+{
+  ((T) 1000000)();
+}
+
+/* { dg-final { scan-assembler "call\t0" } } */
+/* { dg-final { scan-assembler "call\t1000" } } */
+/* { dg-final { scan-assembler "call\t10000" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c
new file mode 100644 (file)
index 0000000..7c991af
--- /dev/null
@@ -0,0 +1,26 @@
+/* Verify proper errors are generated for functions taking too many
+   arguments, with aggregates and 128-bit arguments.  */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+#include <stdint.h>
+
+struct ja
+{
+  long i1;
+  long i2;
+  long i3;
+  long i4;
+  long i5;
+  long i6;
+};
+
+void jorl (struct ja, unsigned __int128, unsigned __int128, int i3);
+
+int foo ()
+{
+  struct ja je;
+  jorl (je, 1, 2, 3); /* { dg-error "too many function arguments" } */
+  return 2L /1;
+}
+
diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c
new file mode 100644 (file)
index 0000000..d9d42c1
--- /dev/null
@@ -0,0 +1,26 @@
+/* Verify proper errors are generated for functions taking too many
+   arguments, with aggregates and 128-bit arguments.  */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+#include <stdint.h>
+
+struct ja
+{
+  long i1;
+  long i2;
+  long i3;
+  long i4;
+  long i5;
+  long i6;
+};
+
+void jorl (struct ja, int, int, int, unsigned __int128);
+
+int foo ()
+{
+  struct ja je;
+  jorl (je, 1, 2, 3, 4); /* { dg-error "too many function arguments" } */
+  return 2L /1;
+}
+
diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs.c b/gcc/testsuite/gcc.target/bpf/diag-funargs.c
new file mode 100644 (file)
index 0000000..d4e9c06
--- /dev/null
@@ -0,0 +1,15 @@
+/* Verify proper errors are generated for functions taking too many
+   arguments.  */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+int
+foo (int a1,  /* { dg-error "too many function arguments" } */
+     int a2,
+     int a3,
+     int a4,
+     int a5,
+     int a6)
+{
+  return a6;
+}
diff --git a/gcc/testsuite/gcc.target/bpf/diag-indcalls.c b/gcc/testsuite/gcc.target/bpf/diag-indcalls.c
new file mode 100644 (file)
index 0000000..9263fcf
--- /dev/null
@@ -0,0 +1,11 @@
+/* Verify proper errors are generated for indirect function calls.  */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+void (*fnp) (void);
+
+void
+foo ()
+{
+  (*fnp) ();
+} /* { dg-error "indirect call in function" } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-bind.c b/gcc/testsuite/gcc.target/bpf/helper-bind.c
new file mode 100644 (file)
index 0000000..2d1fedc
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *addr;
+  int addr_len;
+
+  ret = __builtin_bpf_helper_bind (ctx, addr, addr_len);
+}
+
+/* { dg-final { scan-assembler "call\t64" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c b/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c
new file mode 100644 (file)
index 0000000..844c88d
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  uint32_t ifindex;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_redirect (ifindex, flags);
+}
+
+/* { dg-final { scan-assembler "call\t23" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c b/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c
new file mode 100644 (file)
index 0000000..a4fb813
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t ifindex;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_clone_redirect (skb, ifindex, flags);
+}
+
+/* { dg-final { scan-assembler "call\t13" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c b/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c
new file mode 100644 (file)
index 0000000..ef38192
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int64_t ret;
+  int32_t *to, *from;
+  uint64_t to_size, from_size;
+  int seed;
+
+  ret = __builtin_bpf_helper_csum_diff (from, from_size, to, to_size, seed);
+}
+
+/* { dg-final { scan-assembler "call\t28" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-csum-update.c b/gcc/testsuite/gcc.target/bpf/helper-csum-update.c
new file mode 100644 (file)
index 0000000..3cde867
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int64_t ret;
+  void *skb;
+  int csum;
+
+  ret = __builtin_bpf_helper_csum_update (skb, csum);
+}
+
+/* { dg-final { scan-assembler "call\t40" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c b/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c
new file mode 100644 (file)
index 0000000..a7eb6e6
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *map;
+  uint32_t index;
+
+  ret = __builtin_bpf_helper_current_task_under_cgroup (map, index);
+}
+
+/* { dg-final { scan-assembler "call\t37" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c b/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c
new file mode 100644 (file)
index 0000000..9a9f79d
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *params;
+  int plen;
+  uint32_t flags;
+
+  ret = __builtin_bpf_helper_fib_lookup (ctx, params, plen, flags);
+}
+
+/* { dg-final { scan-assembler "call\t69" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c b/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c
new file mode 100644 (file)
index 0000000..6cfd14d
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint32_t ret;
+  void *skb;
+
+  ret = __builtin_bpf_helper_get_cgroup_classid (skb);
+}
+
+/* { dg-final { scan-assembler "call\t17" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c
new file mode 100644 (file)
index 0000000..916dc4d
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint64_t ret;
+  
+  ret = __builtin_bpf_helper_get_current_cgroup_id ();
+}
+
+/* { dg-final { scan-assembler "call\t80" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c
new file mode 100644 (file)
index 0000000..efc330c
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *buf;
+  uint32_t size_of_buf;
+
+  ret = __builtin_bpf_helper_get_current_comm (buf, size_of_buf);
+}
+
+/* { dg-final { scan-assembler "call\t16" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c
new file mode 100644 (file)
index 0000000..32d3e9c
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint64_t ret;
+
+  ret = __builtin_bpf_helper_get_current_pid_tgid ();
+}
+
+/* { dg-final { scan-assembler "call\t14" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c
new file mode 100644 (file)
index 0000000..016c134
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint64_t ret;
+
+  ret = __builtin_bpf_helper_get_current_task ();
+}
+
+/* { dg-final { scan-assembler "call\t35" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c
new file mode 100644 (file)
index 0000000..1dc2f9f
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint64_t ret;
+
+  ret = __builtin_bpf_helper_get_current_uid_gid ();
+}
+
+/* { dg-final { scan-assembler "call\t15" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c b/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c
new file mode 100644 (file)
index 0000000..1db5d87
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint32_t ret;
+  void *skb;
+
+  ret = __builtin_bpf_helper_get_hash_recalc (skb);
+}
+
+/* { dg-final { scan-assembler "call\t34" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c b/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c
new file mode 100644 (file)
index 0000000..298da1c
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ret, *sk;
+
+  ret = __builtin_bpf_helper_get_listener_sock (sk);
+}
+
+/* { dg-final { scan-assembler "call\t98" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c b/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c
new file mode 100644 (file)
index 0000000..88da67e
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ret, *map;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_get_local_storage (map, flags);
+}
+
+/* { dg-final { scan-assembler "call\t81" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c
new file mode 100644 (file)
index 0000000..628e101
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+
+  ret = __builtin_bpf_helper_get_numa_node_id ();
+}
+
+/* { dg-final { scan-assembler "call\t42" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c b/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c
new file mode 100644 (file)
index 0000000..6d3e5bc
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint32_t ret;
+
+  ret = __builtin_bpf_helper_get_prandom_u32 ();
+}
+
+/* { dg-final { scan-assembler "call\t7" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c b/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c
new file mode 100644 (file)
index 0000000..5056c4a
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint32_t ret;
+  void *skb;
+
+  ret = __builtin_bpf_helper_get_route_realm (skb);
+}
+
+/* { dg-final { scan-assembler "call\t24" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c
new file mode 100644 (file)
index 0000000..655b873
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint32_t ret;
+
+  ret = __builtin_bpf_helper_get_smp_processor_id ();
+}
+
+/* { dg-final { scan-assembler "call\t8" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c b/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c
new file mode 100644 (file)
index 0000000..afd17dd
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint64_t ret;
+  void *skb;
+  
+  ret = __builtin_bpf_helper_get_socket_cookie (skb);
+}
+
+/* { dg-final { scan-assembler "call\t46" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c b/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c
new file mode 100644 (file)
index 0000000..3a274c9
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint32_t ret;
+  void *skb;
+  
+  ret = __builtin_bpf_helper_get_socket_uid (skb);
+}
+
+/* { dg-final { scan-assembler "call\t47" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-stack.c b/gcc/testsuite/gcc.target/bpf/helper-get-stack.c
new file mode 100644 (file)
index 0000000..bbcdeb5
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *regs, *buf;
+  uint32_t size;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_get_stack (regs, buf, size, flags);
+}
+
+/* { dg-final { scan-assembler "call\t67" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c b/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c
new file mode 100644 (file)
index 0000000..319d15c
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *map;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_get_stackid (ctx, map, flags);
+}
+
+/* { dg-final { scan-assembler "call\t27" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c b/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c
new file mode 100644 (file)
index 0000000..fb16f15
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *bpf_socket;
+  int level, optname, optlen;
+  char *optval;
+  
+  ret = __builtin_bpf_helper_getsockopt (bpf_socket, level,
+                                        optname, optval, optlen);
+}
+
+/* { dg-final { scan-assembler "call\t57" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c b/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c
new file mode 100644 (file)
index 0000000..405df05
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint64_t ret;
+  ret = __builtin_bpf_helper_ktime_get_ns ();
+}
+
+/* { dg-final { scan-assembler "call\t5" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c b/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c
new file mode 100644 (file)
index 0000000..ac17662
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t offset;
+  uint64_t from, to, size;
+
+  ret = __builtin_bpf_helper_l3_csum_replace (skb, offset, from, to, size);
+}
+
+/* { dg-final { scan-assembler "call\t10" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c b/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c
new file mode 100644 (file)
index 0000000..52b5514
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t offset;
+  uint64_t from, to, size;
+
+  ret = __builtin_bpf_helper_l4_csum_replace (skb, offset, from, to, size);
+}
+
+/* { dg-final { scan-assembler "call\t11" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c
new file mode 100644 (file)
index 0000000..1baed27
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *hdr;
+  uint32_t type, len;
+  
+  ret = __builtin_bpf_helper_lwt_push_encap (skb, type, hdr, len);
+}
+
+/* { dg-final { scan-assembler "call\t73" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c
new file mode 100644 (file)
index 0000000..ccc94c1
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *param;
+  uint32_t action, param_len;
+  
+  ret = __builtin_bpf_helper_lwt_seg6_action (skb, action,
+                                             param, param_len);
+}
+
+/* { dg-final { scan-assembler "call\t76" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c
new file mode 100644 (file)
index 0000000..5e95124
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t offset, delta;
+  
+  ret = __builtin_bpf_helper_lwt_seg6_adjust_srh (skb, offset,
+                                                 delta);
+}
+
+/* { dg-final { scan-assembler "call\t75" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c
new file mode 100644 (file)
index 0000000..098f976
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *from;
+  uint32_t offset, len;
+  
+  ret = __builtin_bpf_helper_lwt_seg6_store_bytes (skb, offset,
+                                                  from, len);
+}
+
+/* { dg-final { scan-assembler "call\t74" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c
new file mode 100644 (file)
index 0000000..b8a6cde
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+  int ret;
+  char *key = 0;
+
+  ret = __builtin_bpf_helper_map_delete_elem (map (), key);
+}
+
+/* { dg-final { scan-assembler "call\t3" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c
new file mode 100644 (file)
index 0000000..839cfc4
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+  char *key = 0, *value = 0;
+  value = __builtin_bpf_helper_map_lookup_elem (map (), key);
+}
+
+/* { dg-final { scan-assembler "call\t1" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c
new file mode 100644 (file)
index 0000000..6d0acb1
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+  int ret;
+  char *value = 0;
+
+  ret = __builtin_bpf_helper_map_peek_elem (map (), value);
+}
+
+/* { dg-final { scan-assembler "call\t89" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c
new file mode 100644 (file)
index 0000000..71a7851
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+  int ret;
+  char *value = 0;
+
+  ret = __builtin_bpf_helper_map_pop_elem (map (), value);
+}
+
+/* { dg-final { scan-assembler "call\t88" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c
new file mode 100644 (file)
index 0000000..53bc0ac
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+  int ret;
+  char *value = 0;
+  long long flags = 0;
+
+  ret = __builtin_bpf_helper_map_push_elem (map (), value, flags);
+}
+
+/* { dg-final { scan-assembler "call\t87" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c
new file mode 100644 (file)
index 0000000..6281442
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+  int ret;
+  long long flags = 0;
+  char *key = 0, *value = 0;
+
+  ret = __builtin_bpf_helper_map_update_elem (map (), key, value, flags);
+}
+
+/* { dg-final { scan-assembler "call\t2" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c
new file mode 100644 (file)
index 0000000..3b831ac
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *msg;
+  uint32_t bytes;
+  
+  ret = __builtin_bpf_helper_msg_apply_bytes (msg, bytes);
+}
+
+/* { dg-final { scan-assembler "call\t61" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c
new file mode 100644 (file)
index 0000000..2c4ee21
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *msg;
+  uint32_t bytes;
+  
+  ret = __builtin_bpf_helper_msg_cork_bytes (msg, bytes);
+}
+
+/* { dg-final { scan-assembler "call\t62" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c
new file mode 100644 (file)
index 0000000..377c036
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t start, pop;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_msg_pop_data (skb, start, pop, flags);
+}
+
+/* { dg-final { scan-assembler "call\t91" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c
new file mode 100644 (file)
index 0000000..ef27493
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *msg;
+  uint32_t start, end;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_msg_pull_data (msg, start, end, flags);
+}
+
+/* { dg-final { scan-assembler "call\t63" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c
new file mode 100644 (file)
index 0000000..9e256bc
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t start, len;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_msg_push_data (skb, start, len, flags);
+}
+
+/* { dg-final { scan-assembler "call\t90" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c
new file mode 100644 (file)
index 0000000..2e9d413
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *msg, *map, *key;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_msg_redirect_hash (msg, map, key,
+                                               flags);
+}
+
+/* { dg-final { scan-assembler "call\t71" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c
new file mode 100644 (file)
index 0000000..f5f8405
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *msg, *map;
+  uint64_t key;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_msg_redirect_map (msg, map, key,
+                                              flags);
+}
+
+/* { dg-final { scan-assembler "call\t60" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-override-return.c b/gcc/testsuite/gcc.target/bpf/helper-override-return.c
new file mode 100644 (file)
index 0000000..3bd5424
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *regs;
+  uint64_t rc;
+  
+  ret = __builtin_bpf_helper_override_return (regs, rc);
+}
+
+/* { dg-final { scan-assembler "call\t58" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c
new file mode 100644 (file)
index 0000000..afb3201
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *map;
+  uint64_t flags;
+  void *data;
+  uint64_t size;
+
+  ret = __builtin_bpf_helper_perf_event_output (ctx, map, flags, data, size);
+}
+
+/* { dg-final { scan-assembler "call\t25" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c
new file mode 100644 (file)
index 0000000..1d512c9
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *map, *buf;
+  uint64_t flags;
+  uint64_t buf_size;
+  
+  ret = __builtin_bpf_helper_perf_event_read_value (map, flags, buf, buf_size);
+}
+
+/* { dg-final { scan-assembler "call\t55" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c
new file mode 100644 (file)
index 0000000..f099a09
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint64_t ret;
+  void *map;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_perf_event_read (map, flags);
+}
+
+/* { dg-final { scan-assembler "call\t22" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c b/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c
new file mode 100644 (file)
index 0000000..00c4a3a
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *buf;
+  uint64_t buf_size;
+  
+  ret = __builtin_bpf_helper_perf_prog_read_value (ctx, buf, buf_size);
+}
+
+/* { dg-final { scan-assembler "call\t56" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c b/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c
new file mode 100644 (file)
index 0000000..fd04760
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  int size;
+  void *dst;
+  const void *unsafe_ptr;
+  
+  ret = __builtin_bpf_helper_probe_read_str (dst, size, unsafe_ptr);
+}
+
+/* { dg-final { scan-assembler "call\t45" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-read.c b/gcc/testsuite/gcc.target/bpf/helper-probe-read.c
new file mode 100644 (file)
index 0000000..a77a907
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *src, *dst;
+  uint32_t size;
+
+  ret = __builtin_bpf_helper_probe_read (dst, size, src);
+}
+
+/* { dg-final { scan-assembler "call\t4" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c b/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c
new file mode 100644 (file)
index 0000000..bf22620
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *dst, *src;
+  uint32_t len;
+
+  ret = __builtin_bpf_helper_probe_write_user (dst, src, len);
+}
+
+/* { dg-final { scan-assembler "call\t36" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c b/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c
new file mode 100644 (file)
index 0000000..58e9395
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx;
+  uint32_t protocol, toggle;
+  uint64_t scancode;
+  
+  ret = __builtin_bpf_helper_rc_keydown (ctx, protocol,
+                                        scancode, toggle);
+}
+
+/* { dg-final { scan-assembler "call\t78" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c b/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c
new file mode 100644 (file)
index 0000000..e776bc7
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx;
+  int32_t rel_x, rel_y;
+
+  ret = __builtin_bpf_helper_rc_pointer_rel (ctx, rel_x, rel_y);
+}
+
+/* { dg-final { scan-assembler "call\t92" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c b/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c
new file mode 100644 (file)
index 0000000..0ebc7de
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx;
+  
+  ret = __builtin_bpf_helper_rc_repeat (ctx);
+}
+
+/* { dg-final { scan-assembler "call\t77" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c
new file mode 100644 (file)
index 0000000..daeecc2
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *map;
+  uint32_t key;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_redirect_map (map, key, flags);
+}
+
+/* { dg-final { scan-assembler "call\t51" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c b/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c
new file mode 100644 (file)
index 0000000..4bc63ff
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *skb;
+
+  __builtin_bpf_helper_set_hash_invalid (skb);
+}
+
+/* { dg-final { scan-assembler "call\t41" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-set-hash.c b/gcc/testsuite/gcc.target/bpf/helper-set-hash.c
new file mode 100644 (file)
index 0000000..d01ae6e
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint32_t ret;
+  void *skb;
+  uint32_t hash;
+  
+  ret = __builtin_bpf_helper_set_hash (skb, hash);
+}
+
+/* { dg-final { scan-assembler "call\t48" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c b/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c
new file mode 100644 (file)
index 0000000..6f3b450
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *bpf_socket;
+  int level;
+  int optname;
+  void *optval;
+  int optlen;
+  
+  ret = __builtin_bpf_helper_setsockopt (bpf_socket, level, optname,
+                                        optval, optlen);
+}
+
+/* { dg-final { scan-assembler "call\t49" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c b/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c
new file mode 100644 (file)
index 0000000..abe813d
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ret, *sk;
+
+  ret = __builtin_bpf_helper_sk_fullsock (sk);
+}
+
+/* { dg-final { scan-assembler "call\t95" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c
new file mode 100644 (file)
index 0000000..4408640
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ret;
+  void *ctx, *tuple;
+  uint32_t tuple_size;
+  uint64_t netns, flags;
+  
+  ret = __builtin_bpf_helper_sk_lookup_tcp (ctx,
+                                           tuple,
+                                           tuple_size,
+                                           netns, flags);
+}
+
+/* { dg-final { scan-assembler "call\t84" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c
new file mode 100644 (file)
index 0000000..4c50f9c
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ret;
+  void *ctx, *tuple;
+  uint32_t tuple_size;
+  uint64_t netns, flags;
+  
+  ret = __builtin_bpf_helper_sk_lookup_udp (ctx,
+                                           tuple,
+                                           tuple_size,
+                                           netns, flags);
+}
+
+/* { dg-final { scan-assembler "call\t85" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c
new file mode 100644 (file)
index 0000000..7047c9f
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *map, *key;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_sk_redirect_hash (skb, map, key,
+                                              flags);
+}
+
+/* { dg-final { scan-assembler "call\t72" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c
new file mode 100644 (file)
index 0000000..5afb0ac
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *map;
+  uint32_t key;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_sk_redirect_map (ctx, map, key, flags);
+}
+
+/* { dg-final { scan-assembler "call\t52" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-release.c b/gcc/testsuite/gcc.target/bpf/helper-sk-release.c
new file mode 100644 (file)
index 0000000..f054c90
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *sock;
+  
+  ret = __builtin_bpf_helper_sk_release (sock);
+}
+
+/* { dg-final { scan-assembler "call\t86" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c b/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c
new file mode 100644 (file)
index 0000000..399ad2c
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *reuse, *map, *key;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_sk_select_reuseport (reuse, map,
+                                                 key, flags);
+}
+
+/* { dg-final { scan-assembler "call\t82" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c
new file mode 100644 (file)
index 0000000..07c5875
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *map, *sk;
+  
+  ret = __builtin_bpf_helper_sk_storage_delete (map, sk);
+}
+
+/* { dg-final { scan-assembler "call\t108" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c
new file mode 100644 (file)
index 0000000..a199ef0
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ret;
+  void *map, *sk, *value;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_sk_storage_get (map, sk, value,
+                                            flags);
+}
+
+/* { dg-final { scan-assembler "call\t107" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c b/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c
new file mode 100644 (file)
index 0000000..88196f5
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  int32_t len_diff;
+  uint32_t mode;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_skb_adjust_room (skb, len_diff, mode, flags);
+}
+
+/* { dg-final { scan-assembler "call\t50" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c
new file mode 100644 (file)
index 0000000..7c9021e
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  uint64_t ret;
+  void *skb;
+  
+  ret = __builtin_bpf_helper_skb_cgroup_id (skb);
+}
+
+/* { dg-final { scan-assembler "call\t79" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c
new file mode 100644 (file)
index 0000000..de62815
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t len;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_skb_change_head (skb, len, flags);
+}
+
+/* { dg-final { scan-assembler "call\t43" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c
new file mode 100644 (file)
index 0000000..5738f3c
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  int16_t proto;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_skb_change_proto (skb, proto, flags);
+}
+
+/* { dg-final { scan-assembler "call\t31" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c
new file mode 100644 (file)
index 0000000..1fb6b45
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t len;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_skb_change_tail (skb, len, flags);
+}
+
+/* { dg-final { scan-assembler "call\t38" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c
new file mode 100644 (file)
index 0000000..bcf22ce
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t type;
+
+  ret = __builtin_bpf_helper_skb_change_type (skb, type);
+}
+
+/* { dg-final { scan-assembler "call\t32" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c b/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c
new file mode 100644 (file)
index 0000000..f769993
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+
+  ret = __builtin_bpf_helper_skb_ecn_set_ce (skb);
+}
+
+/* { dg-final { scan-assembler "call\t97" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c
new file mode 100644 (file)
index 0000000..0d4db23
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *key;
+  uint32_t size;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_skb_get_tunnel_key (skb, key, size, flags);
+}
+
+/* { dg-final { scan-assembler "call\t20" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c
new file mode 100644 (file)
index 0000000..9428657
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint8_t *opt;
+  uint32_t size;
+
+  ret = __builtin_bpf_helper_skb_get_tunnel_opt (skb, opt, size);
+}
+
+/* { dg-final { scan-assembler "call\t29" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c
new file mode 100644 (file)
index 0000000..8217b4a
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *xfrm_state;
+  uint32_t index, size;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_skb_get_xfrm_state (skb, index,
+                                                xfrm_state, size, flags);
+}
+
+/* { dg-final { scan-assembler "call\t66" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c
new file mode 100644 (file)
index 0000000..bcaa43b
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *to;
+  uint32_t offset, len, start_header;
+
+  ret = __builtin_bpf_helper_skb_load_bytes_relative (skb, offset,
+                                                     to, len,
+                                                     start_header);
+}
+
+/* { dg-final { scan-assembler "call\t68" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c
new file mode 100644 (file)
index 0000000..9da5454
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *to;
+  uint32_t offset, len;
+
+  ret = __builtin_bpf_helper_skb_load_bytes (skb, offset, to, len);
+}
+
+/* { dg-final { scan-assembler "call\t26" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c b/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c
new file mode 100644 (file)
index 0000000..9bb8b8d
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t len;
+
+  ret = __builtin_bpf_helper_skb_pull_data (skb, len);
+}
+
+/* { dg-final { scan-assembler "call\t39" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c
new file mode 100644 (file)
index 0000000..21b835f
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *key;
+  uint32_t size;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_skb_set_tunnel_key (skb, key, size, flags);
+}
+
+/* { dg-final { scan-assembler "call\t21" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c
new file mode 100644 (file)
index 0000000..5a0528e
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint8_t *opt;
+  uint32_t size;
+
+  ret = __builtin_bpf_helper_skb_set_tunnel_opt (skb, opt, size);
+}
+
+/* { dg-final { scan-assembler "call\t30" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c
new file mode 100644 (file)
index 0000000..a41967c
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  uint32_t offset;
+  void *from;
+  uint32_t len;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_skb_store_bytes (skb, offset, from, len, flags);
+}
+
+/* { dg-final { scan-assembler "call\t9" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c b/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c
new file mode 100644 (file)
index 0000000..0ccee8b
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb, *map;
+  uint32_t index;
+
+  ret = __builtin_bpf_helper_skb_under_cgroup (skb, map, index);
+}
+
+/* { dg-final { scan-assembler "call\t33" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c
new file mode 100644 (file)
index 0000000..e99a0ac
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+
+  ret = __builtin_bpf_helper_skb_vlan_pop (skb);
+}
+
+/* { dg-final { scan-assembler "call\t19" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c
new file mode 100644 (file)
index 0000000..dbe52ae
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  int16_t vlan_proto;
+  uint16_t vlan_tci;
+
+  ret = __builtin_bpf_helper_skb_vlan_push (skb, vlan_proto, vlan_tci);
+}
+
+/* { dg-final { scan-assembler "call\t18" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c b/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c
new file mode 100644 (file)
index 0000000..bbc4b99
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ret;
+  void *ctx, *tuple;
+  uint32_t tuple_size;
+  uint64_t netns, flags;
+
+  ret = __builtin_bpf_helper_skc_lookup_tcp (ctx, tuple,
+                                            tuple_size, netns, flags);
+}
+
+/* { dg-final { scan-assembler "call\t99" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c b/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c
new file mode 100644 (file)
index 0000000..bbb77ef
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skops, *map, *key;
+  uint64_t flags;
+
+  ret = __builtin_bpf_helper_sock_hash_update (skops, map, key,
+                                              flags);
+}
+
+/* { dg-final { scan-assembler "call\t70" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c b/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c
new file mode 100644 (file)
index 0000000..301e59e
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skops, *map, *key;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_sock_map_update (skops, map, key,
+                                             flags);
+}
+
+/* { dg-final { scan-assembler "call\t53" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c b/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c
new file mode 100644 (file)
index 0000000..2056312
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *bpf_sock;
+  int argval;
+  
+  ret = __builtin_bpf_helper_sock_ops_cb_flags_set (bpf_sock,
+                                                   argval);
+}
+
+/* { dg-final { scan-assembler "call\t59" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c b/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c
new file mode 100644 (file)
index 0000000..4178914
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *lock;
+
+  __builtin_bpf_helper_spin_lock (lock);
+}
+
+/* { dg-final { scan-assembler "call\t93" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c b/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c
new file mode 100644 (file)
index 0000000..c2416b6
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *lock;
+
+  __builtin_bpf_helper_spin_unlock (lock);
+}
+
+/* { dg-final { scan-assembler "call\t94" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-strtol.c b/gcc/testsuite/gcc.target/bpf/helper-strtol.c
new file mode 100644 (file)
index 0000000..e15b6d6
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+#include <stddef.h>
+
+void
+foo ()
+{
+  int ret;
+  void *buf;
+  long res;
+  uint64_t flags;
+  size_t buf_len;
+  
+  ret = __builtin_bpf_helper_strtol (buf, buf_len, flags, &res);
+}
+
+/* { dg-final { scan-assembler "call\t105" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-strtoul.c b/gcc/testsuite/gcc.target/bpf/helper-strtoul.c
new file mode 100644 (file)
index 0000000..bc0d776
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+#include <stddef.h>
+
+void
+foo ()
+{
+  int ret;
+  void *buf;
+  unsigned long res;
+  uint64_t flags;
+  size_t buf_len;
+  
+  ret = __builtin_bpf_helper_strtoul (buf, buf_len, flags, &res);
+}
+
+/* { dg-final { scan-assembler "call\t106" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c
new file mode 100644 (file)
index 0000000..8035841
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+#include <stddef.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *buf;
+  size_t buf_len;
+  
+  ret = __builtin_bpf_helper_sysctl_get_current_value (ctx, buf,
+                                                      buf_len);
+}
+
+/* { dg-final { scan-assembler "call\t102" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c
new file mode 100644 (file)
index 0000000..a748b4b
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+#include <stddef.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *buf;
+  size_t buf_len;
+  uint64_t flags;
+  
+  ret = __builtin_bpf_helper_sysctl_get_name (ctx, buf,
+                                             buf_len, flags);
+}
+
+/* { dg-final { scan-assembler "call\t101" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c
new file mode 100644 (file)
index 0000000..2c48351
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+#include <stddef.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *buf;
+  size_t buf_len;
+  
+  ret = __builtin_bpf_helper_sysctl_get_new_value (ctx, buf,
+                                                  buf_len);
+}
+
+/* { dg-final { scan-assembler "call\t103" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c
new file mode 100644 (file)
index 0000000..fc3780d
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+#include <stddef.h>
+
+void
+foo ()
+{
+  int ret;
+  void *ctx, *buf;
+  size_t buf_len;
+  
+  ret = __builtin_bpf_helper_sysctl_set_new_value (ctx, buf,
+                                                  buf_len);
+}
+
+/* { dg-final { scan-assembler "call\t104" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-tail-call.c b/gcc/testsuite/gcc.target/bpf/helper-tail-call.c
new file mode 100644 (file)
index 0000000..618064f
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ctx, *prog_array_map;
+  uint32_t index;
+
+  __builtin_bpf_helper_tail_call (ctx, prog_array_map, index);
+}
+
+/* { dg-final { scan-assembler "call\t12" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c b/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c
new file mode 100644 (file)
index 0000000..95846c6
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *sk, *iph, *th;
+  uint32_t iph_len, th_len;
+  
+  ret = __builtin_bpf_helper_tcp_check_syncookie (sk, iph,
+                                                 iph_len,
+                                                 th, th_len);
+}
+
+/* { dg-final { scan-assembler "call\t100" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c b/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c
new file mode 100644 (file)
index 0000000..ab8f2de
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  void *ret, *sk;
+
+  ret = __builtin_bpf_helper_tcp_sock (sk);
+}
+
+/* { dg-final { scan-assembler "call\t96" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c b/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c
new file mode 100644 (file)
index 0000000..fcf9d5c
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+  int ret;
+
+  ret = __builtin_bpf_helper_trace_printk ("foo %d %d", sizeof ("foo %d %d"), 10, 20);
+}
+
+/* { dg-final { scan-assembler "call\t6" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c
new file mode 100644 (file)
index 0000000..3dce543
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *xdp_md;
+  int delta;
+  
+  ret = __builtin_bpf_helper_xdp_adjust_head (xdp_md, delta);
+}
+
+/* { dg-final { scan-assembler "call\t44" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c
new file mode 100644 (file)
index 0000000..38a1374
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *xdp_md;
+  int delta;
+  
+  ret = __builtin_bpf_helper_xdp_adjust_meta (xdp_md, delta);
+}
+
+/* { dg-final { scan-assembler "call\t54" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c
new file mode 100644 (file)
index 0000000..319b65a
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *xdp_md;
+  int delta;
+
+  ret = __builtin_bpf_helper_xdp_adjust_tail (xdp_md, delta);
+}
+
+/* { dg-final { scan-assembler "call\t65" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c
new file mode 100644 (file)
index 0000000..ce193ec
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+  int ret;
+  void *skb;
+  int ancestor_level;
+  
+  ret = __builtin_bpf_helper_skb_ancestor_cgroup_id (skb,
+                                                    ancestor_level);
+}
+
+/* { dg-final { scan-assembler "call\t83" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c b/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c
new file mode 100644 (file)
index 0000000..69949f1
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+long delta;
+long *val;
+
+void
+foo ()
+{
+  __sync_fetch_and_add(val, delta);
+  __sync_fetch_and_add((int *)val, (int)delta);
+}
+
+/* { dg-final { scan-assembler "xadddw\t.*" } } */
+/* { dg-final { scan-assembler "xaddw\t.*" } } */
index 4d03cc0718bc6c9d3230d0af03bf538111b7c1de..3db1902b25c2c045620b3ff006057673d5171bb0 100644 (file)
@@ -526,7 +526,8 @@ proc check_effective_target_trampolines { } {
         || [istarget nvptx-*-*]
         || [istarget hppa2.0w-hp-hpux11.23]
         || [istarget hppa64-hp-hpux11.23]
-        || [istarget pru-*-*] } {
+        || [istarget pru-*-*]
+        || [istarget bpf-*-*] } {
        return 0;
     }
     return 1
@@ -781,7 +782,7 @@ proc add_options_for_tls { flags } {
 # Return 1 if indirect jumps are supported, 0 otherwise.
 
 proc check_effective_target_indirect_jumps {} {
-    if { [istarget nvptx-*-*] } {
+    if { [istarget nvptx-*-*] || [istarget bpf-*-*] } {
        return 0
     }
     return 1
@@ -790,7 +791,7 @@ proc check_effective_target_indirect_jumps {} {
 # Return 1 if nonlocal goto is supported, 0 otherwise.
 
 proc check_effective_target_nonlocal_goto {} {
-    if { [istarget nvptx-*-*] } {
+    if { [istarget nvptx-*-*] || [istarget bpf-*-*] } {
        return 0
     }
     return 1
@@ -799,10 +800,9 @@ proc check_effective_target_nonlocal_goto {} {
 # Return 1 if global constructors are supported, 0 otherwise.
 
 proc check_effective_target_global_constructor {} {
-    if { [istarget nvptx-*-*] } {
-       return 0
-    }
-    if { [istarget amdgcn-*-*] } {
+    if { [istarget nvptx-*-*]
+        || [istarget amdgcn-*-*]
+        || [istarget bpf-*-*] } {
        return 0
     }
     return 1
@@ -825,6 +825,10 @@ proc check_effective_target_return_address {} {
     if { [istarget nvptx-*-*] } {
        return 0
     }
+    # No notion of return address in eBPF.
+    if { [istarget bpf-*-*] } {
+       return 0
+    }
     # It could be supported on amdgcn, but isn't yet.
     if { [istarget amdgcn*-*-*] } {
        return 0
index df5d99684e6f498e7b9c384f92d7b4722cb6ba3e..fdbc009925eb415385e1975a6a74050b58f016b0 100644 (file)
@@ -1,3 +1,10 @@
+2019-09-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       * config.host: Set cpu_type for bpf-*-* targets.
+       * config/bpf/t-bpf: Likewise.
+       * config/bpf/crtn.S: Likewise.
+       * config/bpf/crti.S: New file.
+
 2019-09-06  Jim Wilson  <jimw@sifive.com>
 
        * config.host (riscv*-*-linux*): Add t-slibgcc-libgcc to tmake_file.
index 1db52878a5ea8edc2840507f816c16f7fa717b02..b5826feec46f98f02b965346bf59032e2d861d56 100644 (file)
@@ -107,6 +107,9 @@ avr-*-*)
 bfin*-*)
        cpu_type=bfin
        ;;
+bpf-*-*)
+        cpu_type=bpf
+        ;;
 cr16-*-*)
        ;;
 crisv32-*-*)
@@ -523,6 +526,10 @@ bfin*-*)
        tmake_file="$tmake_file bfin/t-bfin t-fdpbit"
        extra_parts="crtbegin.o crtend.o crti.o crtn.o"
         ;;
+bpf-*-*)
+        tmake_file="$tmake_file ${cpu_type}/t-${cpu_type}"
+        extra_parts="crti.o crtn.o"
+       ;;
 cr16-*-elf)
        tmake_file="${tmake_file} cr16/t-cr16 cr16/t-crtlibid t-fdpbit"
        extra_parts="$extra_parts crti.o crtn.o crtlibid.o"
diff --git a/libgcc/config/bpf/crti.S b/libgcc/config/bpf/crti.S
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/libgcc/config/bpf/crtn.S b/libgcc/config/bpf/crtn.S
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/libgcc/config/bpf/t-bpf b/libgcc/config/bpf/t-bpf
new file mode 100644 (file)
index 0000000..88129a7
--- /dev/null
@@ -0,0 +1,23 @@
+LIB2ADDEH = 
+
+crti.o: $(srcdir)/config/bpf/crti.S
+       $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $<
+
+crtn.o: $(srcdir)/config/bpf/crtn.S
+       $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $<
+
+# Some of the functions defined in libgcc2 exceed the eBPF stack
+# limit, or other restrictions imposed by this peculiar target.
+# Therefore we have to exclude them here.
+#
+# Patterns in bpf.md must guarantee that no calls to the excluded
+# functions are ever generated, and compiler tests should make sure
+# this holds.
+#
+# Note that the modes in the function names below are misleading: di
+# means TImode.
+LIB2FUNCS_EXCLUDE = _mulvdi3 _divdi3 _moddi3 _divmoddi4 _udivdi3 _umoddi3 \
+                    _udivmoddi4
+
+# Prevent building "advanced" stuff (for example, gcov support).
+INHIBIT_LIBC_CFLAGS = -Dinhibit_libc