* [PATCH V4 07/11] bpf: gcc.target eBPF testsuite
2019-08-27 23:51 [PATCH V4 00/11] eBPF support for GCC Jose E. Marchesi
` (5 preceding siblings ...)
2019-08-27 23:49 ` [PATCH V4 10/11] bpf: manual updates for eBPF Jose E. Marchesi
@ 2019-08-27 23:49 ` Jose E. Marchesi
2019-08-27 23:58 ` [PATCH V4 08/11] bpf: make target-supports.exp aware of eBPF Jose E. Marchesi
` (5 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Jose E. Marchesi @ 2019-08-27 23:49 UTC (permalink / raw)
To: gcc-patches
This patch adds a new testsuite to gcc.target, with eBPF specific
tests.
Tests are included for:
- Target specific diagnostics.
- All built-in functions.
testsuite/ChangeLog:
* 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.
* cc.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.
---
gcc/testsuite/ChangeLog | 121 ++++++++++++++++++++-
gcc/testsuite/gcc.target/bpf/bpf.exp | 41 +++++++
gcc/testsuite/gcc.target/bpf/builtin-load.c | 20 ++++
gcc/testsuite/gcc.target/bpf/constant-calls.c | 20 ++++
gcc/testsuite/gcc.target/bpf/diag-funargs-2.c | 26 +++++
gcc/testsuite/gcc.target/bpf/diag-funargs-3.c | 26 +++++
gcc/testsuite/gcc.target/bpf/diag-funargs.c | 15 +++
gcc/testsuite/gcc.target/bpf/diag-indcalls.c | 11 ++
gcc/testsuite/gcc.target/bpf/helper-bind.c | 15 +++
gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c | 15 +++
.../gcc.target/bpf/helper-clone-redirect.c | 16 +++
gcc/testsuite/gcc.target/bpf/helper-csum-diff.c | 16 +++
gcc/testsuite/gcc.target/bpf/helper-csum-update.c | 15 +++
.../bpf/helper-current-task-under-cgroup.c | 15 +++
gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c | 16 +++
.../gcc.target/bpf/helper-get-cgroup-classid.c | 14 +++
.../gcc.target/bpf/helper-get-current-cgroup-id.c | 13 +++
.../gcc.target/bpf/helper-get-current-comm.c | 15 +++
.../gcc.target/bpf/helper-get-current-pid-tgid.c | 13 +++
.../gcc.target/bpf/helper-get-current-task.c | 14 +++
.../gcc.target/bpf/helper-get-current-uid-gid.c | 13 +++
.../gcc.target/bpf/helper-get-hash-recalc.c | 14 +++
.../gcc.target/bpf/helper-get-listener-sock.c | 13 +++
.../gcc.target/bpf/helper-get-local-storage.c | 14 +++
.../gcc.target/bpf/helper-get-numa-node-id.c | 13 +++
.../gcc.target/bpf/helper-get-prandom-u32.c | 13 +++
.../gcc.target/bpf/helper-get-route-realm.c | 14 +++
.../gcc.target/bpf/helper-get-smp-processor-id.c | 13 +++
.../gcc.target/bpf/helper-get-socket-cookie.c | 14 +++
.../gcc.target/bpf/helper-get-socket-uid.c | 14 +++
gcc/testsuite/gcc.target/bpf/helper-get-stack.c | 16 +++
gcc/testsuite/gcc.target/bpf/helper-get-stackid.c | 15 +++
gcc/testsuite/gcc.target/bpf/helper-getsockopt.c | 17 +++
gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c | 12 ++
.../gcc.target/bpf/helper-l3-csum-replace.c | 16 +++
.../gcc.target/bpf/helper-l4-csum-replace.c | 16 +++
.../gcc.target/bpf/helper-lwt-push-encap.c | 15 +++
.../gcc.target/bpf/helper-lwt-seg6-action.c | 16 +++
.../gcc.target/bpf/helper-lwt-seg6-adjust-srh.c | 16 +++
.../gcc.target/bpf/helper-lwt-seg6-store-bytes.c | 16 +++
.../gcc.target/bpf/helper-map-delete-elem.c | 14 +++
.../gcc.target/bpf/helper-map-lookup-elem.c | 12 ++
.../gcc.target/bpf/helper-map-peek-elem.c | 14 +++
gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c | 14 +++
.../gcc.target/bpf/helper-map-push-elem.c | 16 +++
.../gcc.target/bpf/helper-map-update-elem.c | 16 +++
.../gcc.target/bpf/helper-msg-apply-bytes.c | 15 +++
.../gcc.target/bpf/helper-msg-cork-bytes.c | 15 +++
gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c | 16 +++
.../gcc.target/bpf/helper-msg-pull-data.c | 16 +++
.../gcc.target/bpf/helper-msg-push-data.c | 16 +++
.../gcc.target/bpf/helper-msg-redirect-hash.c | 16 +++
.../gcc.target/bpf/helper-msg-redirect-map.c | 17 +++
.../gcc.target/bpf/helper-override-return.c | 15 +++
.../gcc.target/bpf/helper-perf-event-output.c | 17 +++
.../gcc.target/bpf/helper-perf-event-read-value.c | 16 +++
.../gcc.target/bpf/helper-perf-event-read.c | 15 +++
.../gcc.target/bpf/helper-perf-prog-read-value.c | 15 +++
.../gcc.target/bpf/helper-probe-read-str.c | 16 +++
gcc/testsuite/gcc.target/bpf/helper-probe-read.c | 15 +++
.../gcc.target/bpf/helper-probe-write-user.c | 15 +++
gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c | 17 +++
.../gcc.target/bpf/helper-rc-pointer-rel.c | 15 +++
gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c | 14 +++
gcc/testsuite/gcc.target/bpf/helper-redirect-map.c | 16 +++
.../gcc.target/bpf/helper-set-hash-invalid.c | 13 +++
gcc/testsuite/gcc.target/bpf/helper-set-hash.c | 15 +++
gcc/testsuite/gcc.target/bpf/helper-setsockopt.c | 19 ++++
gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c | 13 +++
.../gcc.target/bpf/helper-sk-lookup-tcp.c | 19 ++++
.../gcc.target/bpf/helper-sk-lookup-upd.c | 19 ++++
.../gcc.target/bpf/helper-sk-redirect-hash.c | 16 +++
.../gcc.target/bpf/helper-sk-redirect-map.c | 16 +++
gcc/testsuite/gcc.target/bpf/helper-sk-release.c | 14 +++
.../gcc.target/bpf/helper-sk-select-reuseport.c | 16 +++
.../gcc.target/bpf/helper-sk-storage-delete.c | 14 +++
.../gcc.target/bpf/helper-sk-storage-get.c | 16 +++
.../gcc.target/bpf/helper-skb-adjust-room.c | 17 +++
.../gcc.target/bpf/helper-skb-cgroup-id.c | 14 +++
.../gcc.target/bpf/helper-skb-change-head.c | 16 +++
.../gcc.target/bpf/helper-skb-change-proto.c | 16 +++
.../gcc.target/bpf/helper-skb-change-tail.c | 16 +++
.../gcc.target/bpf/helper-skb-change-type.c | 15 +++
.../gcc.target/bpf/helper-skb-ecn-set-ce.c | 14 +++
.../gcc.target/bpf/helper-skb-get-tunnel-key.c | 16 +++
.../gcc.target/bpf/helper-skb-get-tunnel-opt.c | 16 +++
.../gcc.target/bpf/helper-skb-get-xfrm-state.c | 17 +++
.../bpf/helper-skb-load-bytes-relative.c | 17 +++
.../gcc.target/bpf/helper-skb-load-bytes.c | 15 +++
.../gcc.target/bpf/helper-skb-pull-data.c | 15 +++
.../gcc.target/bpf/helper-skb-set-tunnel-key.c | 16 +++
.../gcc.target/bpf/helper-skb-set-tunnel-opt.c | 16 +++
.../gcc.target/bpf/helper-skb-store-bytes.c | 18 +++
.../gcc.target/bpf/helper-skb-under-cgroup.c | 15 +++
gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c | 14 +++
.../gcc.target/bpf/helper-skb-vlan-push.c | 16 +++
.../gcc.target/bpf/helper-skc-lookup-tcp.c | 17 +++
.../gcc.target/bpf/helper-sock-hash-update.c | 16 +++
.../gcc.target/bpf/helper-sock-map-update.c | 16 +++
.../gcc.target/bpf/helper-sock-ops-cb-flags-set.c | 16 +++
gcc/testsuite/gcc.target/bpf/helper-spin-lock.c | 13 +++
gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c | 13 +++
gcc/testsuite/gcc.target/bpf/helper-strtol.c | 18 +++
gcc/testsuite/gcc.target/bpf/helper-strtoul.c | 18 +++
.../bpf/helper-sysctl-get-current-value.c | 17 +++
.../gcc.target/bpf/helper-sysctl-get-name.c | 18 +++
.../gcc.target/bpf/helper-sysctl-get-new-value.c | 17 +++
.../gcc.target/bpf/helper-sysctl-set-new-value.c | 17 +++
gcc/testsuite/gcc.target/bpf/helper-tail-call.c | 14 +++
.../gcc.target/bpf/helper-tcp-check-syncookie.c | 17 +++
gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c | 13 +++
gcc/testsuite/gcc.target/bpf/helper-trace-printk.c | 13 +++
.../gcc.target/bpf/helper-xdp-adjust-head.c | 15 +++
.../gcc.target/bpf/helper-xdp-adjust-meta.c | 15 +++
.../gcc.target/bpf/helper-xdp-adjust-tail.c | 15 +++
.../gcc.target/bpf/skb-ancestor-cgroup-id.c | 16 +++
gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c | 14 +++
117 files changed, 1946 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/bpf/bpf.exp
create mode 100644 gcc/testsuite/gcc.target/bpf/builtin-load.c
create mode 100644 gcc/testsuite/gcc.target/bpf/constant-calls.c
create mode 100644 gcc/testsuite/gcc.target/bpf/diag-funargs-2.c
create mode 100644 gcc/testsuite/gcc.target/bpf/diag-funargs-3.c
create mode 100644 gcc/testsuite/gcc.target/bpf/diag-funargs.c
create mode 100644 gcc/testsuite/gcc.target/bpf/diag-indcalls.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-bind.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-csum-diff.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-csum-update.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-task.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-stack.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-stackid.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-getsockopt.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-override-return.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-read.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-redirect-map.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-set-hash.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-setsockopt.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-release.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-spin-lock.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-strtol.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-strtoul.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tail-call.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-trace-printk.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c
create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c
create mode 100644 gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c
create mode 100644 gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c
diff --git a/gcc/testsuite/gcc.target/bpf/bpf.exp b/gcc/testsuite/gcc.target/bpf/bpf.exp
new file mode 100644
index 00000000000..e5c8cfcf6b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/bpf.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <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
index 00000000000..0f93d91fb6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/builtin-load.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -std=gnu99" } */
+
+void foo ()
+{
+ long long ll, off;
+
+ /* Indirect. */
+ ll = __builtin_bpf_load_byte (off);
+ ll = __builtin_bpf_load_half (off);
+ ll = __builtin_bpf_load_word (off);
+
+ /* Absolute. */
+ ll = __builtin_bpf_load_byte (0);
+ ll = __builtin_bpf_load_half (4);
+ ll = __builtin_bpf_load_word (8);
+}
+
+/* { dg-final { scan-assembler "ldindb\t%r.,0.*ldindh\t%r.,0.*ldindw\t%r.,0" } } */
+/* { dg-final { scan-assembler "ldabsb\t0.*ldabsh\t4.*ldabsw\t8" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/constant-calls.c b/gcc/testsuite/gcc.target/bpf/constant-calls.c
new file mode 100644
index 00000000000..84612a92ae9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/constant-calls.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-xfail-if "" { bpf-*-* } } */
+
+typedef void *(*T)(void);
+f1 ()
+{
+ ((T) 0)();
+}
+f2 ()
+{
+ ((T) 1000)();
+}
+f3 ()
+{
+ ((T) 1000000)();
+}
+
+/* { dg-final { scan-assembler "call\t0" } } */
+/* { dg-final { scan-assembler "call\t1000" } } */
+/* { dg-final { scan-assembler "call\t10000" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c
new file mode 100644
index 00000000000..7c991af336b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c
@@ -0,0 +1,26 @@
+/* Verify proper errors are generated for functions taking too many
+ arguments, with aggregates and 128-bit arguments. */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+#include <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
index 00000000000..d9d42c18258
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c
@@ -0,0 +1,26 @@
+/* Verify proper errors are generated for functions taking too many
+ arguments, with aggregates and 128-bit arguments. */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+#include <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
index 00000000000..d4e9c0683f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/diag-funargs.c
@@ -0,0 +1,15 @@
+/* Verify proper errors are generated for functions taking too many
+ arguments. */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+int
+foo (int a1, /* { dg-error "too many function arguments" } */
+ int a2,
+ int a3,
+ int a4,
+ int a5,
+ int a6)
+{
+ return a6;
+}
diff --git a/gcc/testsuite/gcc.target/bpf/diag-indcalls.c b/gcc/testsuite/gcc.target/bpf/diag-indcalls.c
new file mode 100644
index 00000000000..9263fcf7e1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/diag-indcalls.c
@@ -0,0 +1,11 @@
+/* Verify proper errors are generated for indirect function calls. */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+void (*fnp) (void);
+
+void
+foo ()
+{
+ (*fnp) ();
+} /* { dg-error "indirect call in function" } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-bind.c b/gcc/testsuite/gcc.target/bpf/helper-bind.c
new file mode 100644
index 00000000000..2d1fedc4ce8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-bind.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..844c88d3e34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c
@@ -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
index 00000000000..a4fb8139234
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c
@@ -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
index 00000000000..ef38192efd3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c
@@ -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
index 00000000000..3cde8678cb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-csum-update.c
@@ -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
index 00000000000..a7eb6e617e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..9a9f79d402c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c
@@ -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
index 00000000000..6cfd14d0ad1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c
@@ -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
index 00000000000..916dc4d3bb1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..efc330c3c98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c
@@ -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
index 00000000000..32d3e9c91d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..c1290f6516e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+void
+foo ()
+{
+ uint64_t ret;
+ void *ctx;
+
+ ret = __builtin_bpf_helper_get_current_task (ctx);
+}
+
+/* { dg-final { scan-assembler "call\t35" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c
new file mode 100644
index 00000000000..1dc2f9f41e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..1db5d871c26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c
@@ -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
index 00000000000..298da1c949b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c
@@ -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
index 00000000000..88da67e99ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c
@@ -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
index 00000000000..628e1012152
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..6d3e5bc7a22
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c
@@ -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
index 00000000000..5056c4adb1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c
@@ -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
index 00000000000..655b87341df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..afd17ddcd50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c
@@ -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
index 00000000000..3a274c965f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c
@@ -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
index 00000000000..bbcdeb58775
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-stack.c
@@ -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
index 00000000000..319d15cd2fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c
@@ -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
index 00000000000..fb16f15e6ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c
@@ -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
index 00000000000..405df057e30
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c
@@ -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
index 00000000000..ac17662c5d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c
@@ -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
index 00000000000..52b5514b6cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c
@@ -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
index 00000000000..1baed27fac7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c
@@ -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
index 00000000000..ccc94c1af9d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c
@@ -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
index 00000000000..5e95124ad0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..098f97680f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..b8a6cdec4ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+ int ret;
+ char *key = 0;
+
+ ret = __builtin_bpf_helper_map_delete_elem (map (), key);
+}
+
+/* { dg-final { scan-assembler "call\t3" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c
new file mode 100644
index 00000000000..839cfc423a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+ char *key = 0, *value = 0;
+ value = __builtin_bpf_helper_map_lookup_elem (map (), key);
+}
+
+/* { dg-final { scan-assembler "call\t1" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c
new file mode 100644
index 00000000000..6d0acb1dcb7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+ int ret;
+ char *value = 0;
+
+ ret = __builtin_bpf_helper_map_peek_elem (map (), value);
+}
+
+/* { dg-final { scan-assembler "call\t89" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c
new file mode 100644
index 00000000000..71a7851ca9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+ int ret;
+ char *value = 0;
+
+ ret = __builtin_bpf_helper_map_pop_elem (map (), value);
+}
+
+/* { dg-final { scan-assembler "call\t88" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c
new file mode 100644
index 00000000000..53bc0ac5dd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+ int ret;
+ char *value = 0;
+ long long flags = 0;
+
+ ret = __builtin_bpf_helper_map_push_elem (map (), value, flags);
+}
+
+/* { dg-final { scan-assembler "call\t87" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c
new file mode 100644
index 00000000000..6281442ba3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+ int ret;
+ long long flags = 0;
+ char *key = 0, *value = 0;
+
+ ret = __builtin_bpf_helper_map_update_elem (map (), key, value, flags);
+}
+
+/* { dg-final { scan-assembler "call\t2" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c
new file mode 100644
index 00000000000..3b831acad64
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..2c4ee218832
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c
@@ -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
index 00000000000..377c036603e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c
@@ -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
index 00000000000..ef27493122b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c
@@ -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
index 00000000000..9e256bc5ca7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c
@@ -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
index 00000000000..2e9d4137d66
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c
@@ -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
index 00000000000..f5f8405e324
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c
@@ -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
index 00000000000..3bd5424353f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-override-return.c
@@ -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
index 00000000000..afb32010bdd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c
@@ -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
index 00000000000..1d512c9ec65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..f099a09d66f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c
@@ -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
index 00000000000..00c4a3a78b5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..fd04760221d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c
@@ -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
index 00000000000..a77a907767b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-probe-read.c
@@ -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
index 00000000000..bf226206769
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c
@@ -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
index 00000000000..58e9395dbeb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c
@@ -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
index 00000000000..e776bc75963
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c
@@ -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
index 00000000000..0ebc7de5bdf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c
@@ -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
index 00000000000..daeecc2a01e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c
@@ -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
index 00000000000..4bc63ffa063
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c
@@ -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
index 00000000000..d01ae6eb268
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-set-hash.c
@@ -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
index 00000000000..6f3b450639e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c
@@ -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
index 00000000000..abe813d94f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c
@@ -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
index 00000000000..4408640a6b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c
@@ -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
index 00000000000..4c50f9c6327
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c
@@ -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
index 00000000000..7047c9f1290
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c
@@ -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
index 00000000000..5afb0ac4100
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c
@@ -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
index 00000000000..f054c90652c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-release.c
@@ -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
index 00000000000..399ad2c0231
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c
@@ -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
index 00000000000..07c5875d930
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c
@@ -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
index 00000000000..a199ef0ae64
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c
@@ -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
index 00000000000..88196f5e070
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c
@@ -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
index 00000000000..7c9021e1763
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c
@@ -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
index 00000000000..de6281539fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c
@@ -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
index 00000000000..5738f3cc59b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c
@@ -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
index 00000000000..1fb6b45cd1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c
@@ -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
index 00000000000..bcf22cebc28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c
@@ -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
index 00000000000..f769993f120
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..0d4db236865
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..9428657b932
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..8217b4a17df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..bcaa43be9de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..9da545400c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c
@@ -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
index 00000000000..9bb8b8d6e78
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c
@@ -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
index 00000000000..21b835f5cef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..5a0528ec0a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..a41967cb904
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c
@@ -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
index 00000000000..0ccee8bed5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c
@@ -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
index 00000000000..e99a0ac7802
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c
@@ -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
index 00000000000..dbe52aee1b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c
@@ -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
index 00000000000..bbc4b99a808
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c
@@ -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
index 00000000000..bbb77ef9ad5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c
@@ -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
index 00000000000..301e59e975b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c
@@ -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
index 00000000000..2056312bcf3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..4178914ae13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c
@@ -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
index 00000000000..c2416b66994
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c
@@ -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
index 00000000000..e15b6d6b968
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-strtol.c
@@ -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
index 00000000000..bc0d77656d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-strtoul.c
@@ -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
index 00000000000..803584171dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..a748b4bf911
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c
@@ -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
index 00000000000..2c4835100c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..fc3780da7e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..618064f4aea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-tail-call.c
@@ -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
index 00000000000..95846c6f2d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c
@@ -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
index 00000000000..ab8f2de05d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c
@@ -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
index 00000000000..fcf9d5c9e50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+char *map () { return 0; }
+
+void
+foo ()
+{
+ int ret;
+
+ ret = __builtin_bpf_helper_trace_printk ("foo %d %d", sizeof ("foo %d %d"), 10, 20);
+}
+
+/* { dg-final { scan-assembler "call\t6" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c
new file mode 100644
index 00000000000..3dce5434535
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <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
index 00000000000..38a13748737
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c
@@ -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
index 00000000000..319b65a233d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c
@@ -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
index 00000000000..ce193ec14bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c
@@ -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
index 00000000000..69949f14d0c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+long delta;
+long *val;
+
+void
+foo ()
+{
+ __sync_fetch_and_add(val, delta);
+ __sync_fetch_and_add((int *)val, (int)delta);
+}
+
+/* { dg-final { scan-assembler "xadddw\t.*" } } */
+/* { dg-final { scan-assembler "xaddw\t.*" } } */
--
2.11.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH V4 09/11] bpf: adjust GCC testsuite to eBPF limitations
2019-08-27 23:51 [PATCH V4 00/11] eBPF support for GCC Jose E. Marchesi
` (8 preceding siblings ...)
2019-08-28 0:37 ` [PATCH V4 02/11] opt-functions.awk: fix comparison of limit, begin and end Jose E. Marchesi
@ 2019-08-28 0:43 ` Jose E. Marchesi
2019-08-28 1:18 ` [PATCH V4 05/11] bpf: new GCC port Jose E. Marchesi
` (2 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Jose E. Marchesi @ 2019-08-28 0:43 UTC (permalink / raw)
To: gcc-patches
This patch makes many tests in gcc.dg and gcc.c-torture to be skipped
in bpf-*-* targets. This is due to the many limitations imposed by
eBPF to what would be perfectly valid C code: no support for more than
5 arguments to function calls, no support for indirect jumps, a very
limited range for direct jumps, etc.
Hopefully some of these restrictions will be relaxed in the future.
Also, as semantics associated with object linking get developed in
eBPF, it may be possible at some point to provide a set of standard
run-time libraries for eBPF programs.
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/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.
---
gcc/testsuite/ChangeLog | 85 ++++++++++++++++++++++
gcc/testsuite/gcc.c-torture/compile/20000211-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/20000403-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/20000804-1.c | 1 +
gcc/testsuite/gcc.c-torture/compile/20001226-1.c | 1 +
gcc/testsuite/gcc.c-torture/compile/20030903-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/20031125-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/20040101-1.c | 1 +
gcc/testsuite/gcc.c-torture/compile/20040317-2.c | 2 +
gcc/testsuite/gcc.c-torture/compile/20040726-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/20051216-1.c | 1 +
gcc/testsuite/gcc.c-torture/compile/20101217-1.c | 4 +-
gcc/testsuite/gcc.c-torture/compile/900313-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/920501-7.c | 1 +
gcc/testsuite/gcc.c-torture/compile/920625-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/930421-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/930623-1.c | 1 +
gcc/testsuite/gcc.c-torture/compile/961004-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/980504-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/980816-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/990625-1.c | 2 +
gcc/testsuite/gcc.c-torture/compile/DFcmp.c | 2 +
gcc/testsuite/gcc.c-torture/compile/HIcmp.c | 2 +
gcc/testsuite/gcc.c-torture/compile/HIset.c | 2 +
gcc/testsuite/gcc.c-torture/compile/QIcmp.c | 2 +
gcc/testsuite/gcc.c-torture/compile/QIset.c | 2 +
gcc/testsuite/gcc.c-torture/compile/SFset.c | 1 +
gcc/testsuite/gcc.c-torture/compile/SIcmp.c | 2 +
gcc/testsuite/gcc.c-torture/compile/SIset.c | 2 +
gcc/testsuite/gcc.c-torture/compile/UHIcmp.c | 2 +
gcc/testsuite/gcc.c-torture/compile/UQIcmp.c | 2 +
gcc/testsuite/gcc.c-torture/compile/USIcmp.c | 2 +
gcc/testsuite/gcc.c-torture/compile/consec.c | 2 +
.../gcc.c-torture/compile/limits-fndefn.c | 1 +
gcc/testsuite/gcc.c-torture/compile/lll.c | 1 +
gcc/testsuite/gcc.c-torture/compile/parms.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pass.c | 2 +
gcc/testsuite/gcc.c-torture/compile/poor.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pp.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr25311.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr32399.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr34091.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr34688.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr37258.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr37327.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr37381.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr37669-2.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr37669.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr37742-3.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr44063.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr48596.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr51856.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr54428.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr54713-1.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr54713-2.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr54713-3.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr55921.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr70240.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr70355.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr82052.c | 2 +
gcc/testsuite/gcc.c-torture/compile/pr83487.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pr86122.c | 1 +
gcc/testsuite/gcc.c-torture/compile/pret-arg.c | 2 +
.../gcc.c-torture/compile/regs-arg-size.c | 2 +
gcc/testsuite/gcc.c-torture/compile/structret.c | 2 +
gcc/testsuite/gcc.c-torture/compile/uuarg.c | 2 +
gcc/testsuite/gcc.dg/20001009-1.c | 1 +
gcc/testsuite/gcc.dg/20020418-1.c | 1 +
gcc/testsuite/gcc.dg/20020426-2.c | 1 +
gcc/testsuite/gcc.dg/20020430-1.c | 1 +
gcc/testsuite/gcc.dg/20040306-1.c | 2 +-
gcc/testsuite/gcc.dg/20040622-2.c | 1 +
gcc/testsuite/gcc.dg/20050603-2.c | 1 +
gcc/testsuite/gcc.dg/20050629-1.c | 1 +
gcc/testsuite/gcc.dg/20061026.c | 1 +
gcc/testsuite/gcc.dg/Warray-bounds-3.c | 1 +
gcc/testsuite/gcc.dg/Warray-bounds-30.c | 3 +-
gcc/testsuite/gcc.dg/Wframe-larger-than-2.c | 3 +-
gcc/testsuite/gcc.dg/Wframe-larger-than.c | 1 +
gcc/testsuite/gcc.dg/Wrestrict-11.c | 3 +-
gcc/testsuite/gcc.dg/builtins-config.h | 4 +-
81 files changed, 216 insertions(+), 6 deletions(-)
diff --git a/gcc/testsuite/gcc.c-torture/compile/20000211-1.c b/gcc/testsuite/gcc.c-torture/compile/20000211-1.c
index 7a7c8c0cb20..b83d6a40520 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20000211-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20000211-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef __SIZE_TYPE__ size_t;
typedef unsigned char Bufbyte;
typedef int Bytecount;
diff --git a/gcc/testsuite/gcc.c-torture/compile/20000403-1.c b/gcc/testsuite/gcc.c-torture/compile/20000403-1.c
index 27345b56fef..cb56028fb8b 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20000403-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20000403-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
struct utsname {
char sysname[32 ];
char version[32 ];
diff --git a/gcc/testsuite/gcc.c-torture/compile/20000804-1.c b/gcc/testsuite/gcc.c-torture/compile/20000804-1.c
index 550669b53a3..95bb0fafd70 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20000804-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20000804-1.c
@@ -5,6 +5,7 @@
/* { dg-skip-if "No 64-bit registers" { m32c-*-* } } */
/* { dg-skip-if "Not enough 64-bit registers" { pdp11-*-* } { "-O0" } { "" } } */
/* { dg-xfail-if "Inconsistent constraint on asm" { csky-*-* } { "-O0" } { "" } } */
+/* { dg-xfail-if "Inconsistent constraint on asm" { bpf-*-* } { "-O0" } { "" } } */
/* { dg-xfail-if "" { h8300-*-* } } */
/* { dg-require-stack-size "99*4+16" } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c
index be0bdcf7631..9f6bd0af2e5 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c
@@ -3,6 +3,7 @@
/* { dg-skip-if "too much code for pdp11" { "pdp11-*-*" } } */
/* { dg-xfail-if "PR36698" { spu-*-* } { "-O0" } { "" } } */
/* { dg-skip-if "" { m32c-*-* } } */
+/* { dg-skip-if "jumps too far for eBPF" { bpf-*-* } } */
/* { dg-timeout-factor 4.0 } */
/* This testcase exposed two branch shortening bugs on powerpc. */
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030903-1.c b/gcc/testsuite/gcc.c-torture/compile/20030903-1.c
index fa4d30db6c0..116b0923721 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20030903-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20030903-1.c
@@ -1,6 +1,8 @@
/* Derived from PR optimization/11700. */
/* The compiler used to ICE during reload for m68k targets. */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
void check_complex (__complex__ double, __complex__ double,
__complex__ double, __complex__ int);
void check_float (double, double, double, int);
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031125-1.c b/gcc/testsuite/gcc.c-torture/compile/20031125-1.c
index d3e92679c8b..bec6c9372a8 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20031125-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20031125-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
short *_offsetTable;
/* This tests to make sure PRE splits the entry block ->block 0 edge
when there are multiple block 0 predecessors.
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040101-1.c b/gcc/testsuite/gcc.c-torture/compile/20040101-1.c
index 5c2688ad830..6027cb53fb4 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20040101-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20040101-1.c
@@ -1,4 +1,5 @@
/* { dg-skip-if "not enough registers" { pdp11-*-* } } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040317-2.c b/gcc/testsuite/gcc.c-torture/compile/20040317-2.c
index 3c8ee2b8ec5..3a1fbde2969 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20040317-2.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20040317-2.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef struct _ScaleRec *ScaleWidget;
typedef struct
{
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040726-1.c b/gcc/testsuite/gcc.c-torture/compile/20040726-1.c
index e53ccd655bb..aea43a56f34 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20040726-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20040726-1.c
@@ -1,4 +1,6 @@
/* PR rtl-optimization/16643 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
void foo (int a, int b, int c, int d, int e, int *f)
{
if (a == 0)
diff --git a/gcc/testsuite/gcc.c-torture/compile/20051216-1.c b/gcc/testsuite/gcc.c-torture/compile/20051216-1.c
index ed6ac723069..55751ec8ab2 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20051216-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20051216-1.c
@@ -1,4 +1,5 @@
/* PR rtl-optimization/25432 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
void *malloc (__SIZE_TYPE__);
void *realloc (void *, __SIZE_TYPE__);
diff --git a/gcc/testsuite/gcc.c-torture/compile/20101217-1.c b/gcc/testsuite/gcc.c-torture/compile/20101217-1.c
index c4eef0ed464..46bdcf5e347 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20101217-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20101217-1.c
@@ -1,5 +1,7 @@
/* Testcase provided by HUAWEI. */
-#include <stdio.h>
+
+extern int printf (const char * __format, ...);
+
int main()
{
int cur_k;
diff --git a/gcc/testsuite/gcc.c-torture/compile/900313-1.c b/gcc/testsuite/gcc.c-torture/compile/900313-1.c
index 2bac5814a7b..12252b4b229 100644
--- a/gcc/testsuite/gcc.c-torture/compile/900313-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/900313-1.c
@@ -1,4 +1,6 @@
/* { dg-require-effective-target alloca } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
main ()
{
char *a;
diff --git a/gcc/testsuite/gcc.c-torture/compile/920501-7.c b/gcc/testsuite/gcc.c-torture/compile/920501-7.c
index 2af15e3b7ec..0fac5f3495f 100644
--- a/gcc/testsuite/gcc.c-torture/compile/920501-7.c
+++ b/gcc/testsuite/gcc.c-torture/compile/920501-7.c
@@ -1,3 +1,4 @@
/* { dg-require-effective-target label_values } */
+/* { dg-skip-if "no support for indirect jumps" { bpf-*-* } } */
x(){if(&&e-&&b<0)x();b:goto*&&b;e:;}
diff --git a/gcc/testsuite/gcc.c-torture/compile/920625-1.c b/gcc/testsuite/gcc.c-torture/compile/920625-1.c
index 720d43fd42f..759a356b5b7 100644
--- a/gcc/testsuite/gcc.c-torture/compile/920625-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/920625-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef unsigned long int unsigned_word;
typedef signed long int signed_word;
typedef unsigned_word word;
diff --git a/gcc/testsuite/gcc.c-torture/compile/930421-1.c b/gcc/testsuite/gcc.c-torture/compile/930421-1.c
index 01b465f7fec..9e16fe17dd9 100644
--- a/gcc/testsuite/gcc.c-torture/compile/930421-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/930421-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
double q(double);
f (int **x, int *r, int *s, int a, int b, int c, int d)
diff --git a/gcc/testsuite/gcc.c-torture/compile/930623-1.c b/gcc/testsuite/gcc.c-torture/compile/930623-1.c
index 022ad01804e..dd45bbccc38 100644
--- a/gcc/testsuite/gcc.c-torture/compile/930623-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/930623-1.c
@@ -1,4 +1,5 @@
/* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "no __builtin_apply in eBPF" { bpf-*-* } } */
g (a, b) {}
diff --git a/gcc/testsuite/gcc.c-torture/compile/961004-1.c b/gcc/testsuite/gcc.c-torture/compile/961004-1.c
index 6407b625d66..cf47f60d5ea 100644
--- a/gcc/testsuite/gcc.c-torture/compile/961004-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/961004-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
void
f1 (o1, o2, o3, i, j, k)
long long *o1, *o2, *o3;
diff --git a/gcc/testsuite/gcc.c-torture/compile/980504-1.c b/gcc/testsuite/gcc.c-torture/compile/980504-1.c
index 7b757ccd2e8..6e043a7af19 100644
--- a/gcc/testsuite/gcc.c-torture/compile/980504-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/980504-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef struct _geom_elem {
double coeffs[6];
} pGeomDefRec, *pGeomDefPtr;
diff --git a/gcc/testsuite/gcc.c-torture/compile/980816-1.c b/gcc/testsuite/gcc.c-torture/compile/980816-1.c
index a79100fab57..5bd83b17063 100644
--- a/gcc/testsuite/gcc.c-torture/compile/980816-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/980816-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef __SIZE_TYPE__ size_t;
typedef void *XtPointer;
diff --git a/gcc/testsuite/gcc.c-torture/compile/990625-1.c b/gcc/testsuite/gcc.c-torture/compile/990625-1.c
index 97a2331c7a5..befff06579e 100644
--- a/gcc/testsuite/gcc.c-torture/compile/990625-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/990625-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "no string.h in eBPF" { bpf-*-* } } */
+
#define __USE_STRING_INLINES
#include <string.h>
diff --git a/gcc/testsuite/gcc.c-torture/compile/DFcmp.c b/gcc/testsuite/gcc.c-torture/compile/DFcmp.c
index 3bb253476d7..808874de1a8 100644
--- a/gcc/testsuite/gcc.c-torture/compile/DFcmp.c
+++ b/gcc/testsuite/gcc.c-torture/compile/DFcmp.c
@@ -1,4 +1,6 @@
/* { dg-require-effective-target int32plus } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define type double
type glob0, glob1;
diff --git a/gcc/testsuite/gcc.c-torture/compile/HIcmp.c b/gcc/testsuite/gcc.c-torture/compile/HIcmp.c
index 77b47886ed1..6e68271a009 100644
--- a/gcc/testsuite/gcc.c-torture/compile/HIcmp.c
+++ b/gcc/testsuite/gcc.c-torture/compile/HIcmp.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define type short
type glob0, glob1;
diff --git a/gcc/testsuite/gcc.c-torture/compile/HIset.c b/gcc/testsuite/gcc.c-torture/compile/HIset.c
index 163cb7cbe32..a0d426c2c07 100644
--- a/gcc/testsuite/gcc.c-torture/compile/HIset.c
+++ b/gcc/testsuite/gcc.c-torture/compile/HIset.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define E0 ((type *)10000000)
#define reg0 r0
#define indreg0 (*p0)
diff --git a/gcc/testsuite/gcc.c-torture/compile/QIcmp.c b/gcc/testsuite/gcc.c-torture/compile/QIcmp.c
index c5161646f2c..a4dba2487e4 100644
--- a/gcc/testsuite/gcc.c-torture/compile/QIcmp.c
+++ b/gcc/testsuite/gcc.c-torture/compile/QIcmp.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define type signed char
type glob0, glob1;
diff --git a/gcc/testsuite/gcc.c-torture/compile/QIset.c b/gcc/testsuite/gcc.c-torture/compile/QIset.c
index 212609dc864..e2fde2bda7e 100644
--- a/gcc/testsuite/gcc.c-torture/compile/QIset.c
+++ b/gcc/testsuite/gcc.c-torture/compile/QIset.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define E0 ((type *)10000000)
#define reg0 r0
#define indreg0 (*p0)
diff --git a/gcc/testsuite/gcc.c-torture/compile/SFset.c b/gcc/testsuite/gcc.c-torture/compile/SFset.c
index dc7f48dd2dd..a7efecf9717 100644
--- a/gcc/testsuite/gcc.c-torture/compile/SFset.c
+++ b/gcc/testsuite/gcc.c-torture/compile/SFset.c
@@ -1,4 +1,5 @@
/* { dg-require-effective-target int32plus } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define E0 ((type *)10000000)
#define reg0 r0
diff --git a/gcc/testsuite/gcc.c-torture/compile/SIcmp.c b/gcc/testsuite/gcc.c-torture/compile/SIcmp.c
index 4a9e0d57fd7..ce1281b6093 100644
--- a/gcc/testsuite/gcc.c-torture/compile/SIcmp.c
+++ b/gcc/testsuite/gcc.c-torture/compile/SIcmp.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define type int
type glob0, glob1;
diff --git a/gcc/testsuite/gcc.c-torture/compile/SIset.c b/gcc/testsuite/gcc.c-torture/compile/SIset.c
index 5fb93579f4b..b200a264b95 100644
--- a/gcc/testsuite/gcc.c-torture/compile/SIset.c
+++ b/gcc/testsuite/gcc.c-torture/compile/SIset.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define E0 ((type *)10000000)
#define reg0 r0
#define indreg0 (*p0)
diff --git a/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c b/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c
index 529e3a33fd3..b0029d23ea4 100644
--- a/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c
+++ b/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define type unsigned short
type glob0, glob1;
diff --git a/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c b/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c
index 3e9cdebc903..e28d13b03ab 100644
--- a/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c
+++ b/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define type unsigned char
type glob0, glob1;
diff --git a/gcc/testsuite/gcc.c-torture/compile/USIcmp.c b/gcc/testsuite/gcc.c-torture/compile/USIcmp.c
index 69788a45b2e..27e5503bd4d 100644
--- a/gcc/testsuite/gcc.c-torture/compile/USIcmp.c
+++ b/gcc/testsuite/gcc.c-torture/compile/USIcmp.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
#define type unsigned int
type glob0, glob1;
diff --git a/gcc/testsuite/gcc.c-torture/compile/consec.c b/gcc/testsuite/gcc.c-torture/compile/consec.c
index 01fa25b009b..b8c376d7076 100644
--- a/gcc/testsuite/gcc.c-torture/compile/consec.c
+++ b/gcc/testsuite/gcc.c-torture/compile/consec.c
@@ -1,4 +1,6 @@
/* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
int glob;
conseq (a, b, c, d)
diff --git a/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c b/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c
index 0bd8f6af995..53204735493 100644
--- a/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c
+++ b/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c
@@ -1,5 +1,6 @@
/* { dg-skip-if "too complex for avr" { avr-*-* } } */
/* { dg-skip-if "ptxas times out" { nvptx-*-* } } */
+/* { dg-skip-if "no chance for bpf" { bpf-*-* } } */
/* { dg-timeout-factor 4.0 } */
#define LIM1(x) x##0, x##1, x##2, x##3, x##4, x##5, x##6, x##7, x##8, x##9,
#define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \
diff --git a/gcc/testsuite/gcc.c-torture/compile/lll.c b/gcc/testsuite/gcc.c-torture/compile/lll.c
index dee9dc37d15..ea09c871c6b 100644
--- a/gcc/testsuite/gcc.c-torture/compile/lll.c
+++ b/gcc/testsuite/gcc.c-torture/compile/lll.c
@@ -1,3 +1,4 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
byte_match_count2 (buf, n, xm, m1, m2, m3, m4)
unsigned *buf;
diff --git a/gcc/testsuite/gcc.c-torture/compile/parms.c b/gcc/testsuite/gcc.c-torture/compile/parms.c
index 8205a9c1454..1bfc93d2abb 100644
--- a/gcc/testsuite/gcc.c-torture/compile/parms.c
+++ b/gcc/testsuite/gcc.c-torture/compile/parms.c
@@ -1,4 +1,5 @@
/* { dg-require-effective-target alloca } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define alloca __builtin_alloca
x (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, x, y)
diff --git a/gcc/testsuite/gcc.c-torture/compile/pass.c b/gcc/testsuite/gcc.c-torture/compile/pass.c
index 4e028393feb..529a01dac85 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pass.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pass.c
@@ -1,4 +1,6 @@
/* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
int
foo (a, b, c)
{
diff --git a/gcc/testsuite/gcc.c-torture/compile/poor.c b/gcc/testsuite/gcc.c-torture/compile/poor.c
index 66d584aff43..20287ef2354 100644
--- a/gcc/testsuite/gcc.c-torture/compile/poor.c
+++ b/gcc/testsuite/gcc.c-torture/compile/poor.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
typedef struct
{
char c[510];
diff --git a/gcc/testsuite/gcc.c-torture/compile/pp.c b/gcc/testsuite/gcc.c-torture/compile/pp.c
index 7d38d53de0f..c1e09eab407 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pp.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pp.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
foo (a, b, c, d, e, i0, f, i1)
double a, b, c, d, e, f;
int i0, i1;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr25311.c b/gcc/testsuite/gcc.c-torture/compile/pr25311.c
index 26c5bc37b83..43ef3fd9523 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr25311.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr25311.c
@@ -1,3 +1,4 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
struct w
{
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr32399.c b/gcc/testsuite/gcc.c-torture/compile/pr32399.c
index cc2b1b18984..b29dbd7986a 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr32399.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr32399.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
void f(unsigned char *src, unsigned char *dst, int num, unsigned char *pos, unsigned char *diffuse, int hasdiffuse, unsigned char *specular, int hasspecular) {
int i;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34091.c b/gcc/testsuite/gcc.c-torture/compile/pr34091.c
index 0b8549132e6..a623a383fd0 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr34091.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr34091.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef unsigned int GLenum;
typedef unsigned char GLboolean;
typedef int GLint;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34688.c b/gcc/testsuite/gcc.c-torture/compile/pr34688.c
index 60e0f3c9f15..ec890cb8f15 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr34688.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr34688.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef __SIZE_TYPE__ size_t;
typedef struct {
}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37258.c b/gcc/testsuite/gcc.c-torture/compile/pr37258.c
index 286f2fc4427..41801781e3a 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr37258.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37258.c
@@ -1,4 +1,6 @@
/* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37327.c b/gcc/testsuite/gcc.c-torture/compile/pr37327.c
index 79946b7522d..5ca9d1d45b6 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr37327.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37327.c
@@ -1,4 +1,6 @@
/* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37381.c b/gcc/testsuite/gcc.c-torture/compile/pr37381.c
index a2fed66c4ee..d8cd47d329d 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr37381.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37381.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
extern unsigned int __invalid_size_argument_for_IOC;
typedef unsigned int __u32;
struct video_window
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c b/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c
index abeae7a2f32..2170dda67f0 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c
@@ -1,4 +1,5 @@
/* PR middle-end/37669 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#define FMT10 "%d%d%d%d%d%d%d%d%d%d"
#define FMT100 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37669.c b/gcc/testsuite/gcc.c-torture/compile/pr37669.c
index a2eafc75cb3..36e4c39d8ed 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr37669.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37669.c
@@ -1,6 +1,7 @@
/* This testcase used to fail because a miscompiled execute_fold_all_builtins. */
/* { dg-options "-fgnu89-inline" } */
/* { dg-require-effective-target int32plus } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef __SIZE_TYPE__ size_t;
extern __inline __attribute__ ((__always_inline__)) int __attribute__
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c b/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c
index 541bd42ad5d..9e7b10fb7a3 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
void matmul_i4 (int * __restrict dest_y,
const int * __restrict abase,
const int * __restrict bbase_y,
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr44063.c b/gcc/testsuite/gcc.c-torture/compile/pr44063.c
index 596e1dc991f..32208f610f9 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr44063.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr44063.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
typedef signed char int8_t;
typedef short int16_t;
typedef unsigned char uint8_t;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr48596.c b/gcc/testsuite/gcc.c-torture/compile/pr48596.c
index 382a152413e..743bd82e868 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr48596.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr48596.c
@@ -1,4 +1,6 @@
/* PR target/48596 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
enum { nrrdCenterUnknown, nrrdCenterNode, nrrdCenterCell, nrrdCenterLast };
typedef struct { int size; int center; } NrrdAxis;
typedef struct { int dim; NrrdAxis axis[10]; } Nrrd;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr51856.c b/gcc/testsuite/gcc.c-torture/compile/pr51856.c
index 6644c7fdc14..823a0bed073 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr51856.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr51856.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
struct B { int b1; long long b2, b3; int b4; };
struct C { char c1[40], c2, c3[96]; long long c4[5], c5; char c6[596]; };
void fn1 (long long), fn2 (char *, int), fn4 (void);
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54428.c b/gcc/testsuite/gcc.c-torture/compile/pr54428.c
index 84a5dbd82bd..d783337cfdb 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr54428.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr54428.c
@@ -1,4 +1,5 @@
/* PR c/54428 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef double _Complex C;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c
index f042ea2fc6c..0d4172a576b 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c
@@ -1,4 +1,5 @@
/* PR tree-optimization/54713 */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
#ifndef N
#define N 8
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c
index c3910373111..f7d2364e197 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c
@@ -1,4 +1,5 @@
/* PR tree-optimization/54713 */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
#define N 16
#define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c
index 6164a5eec0e..76a35b067c5 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c
@@ -1,4 +1,5 @@
/* PR tree-optimization/54713 */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
#define N 32
#define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr55921.c b/gcc/testsuite/gcc.c-torture/compile/pr55921.c
index de0635d66ad..cf9084e33f0 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr55921.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr55921.c
@@ -1,5 +1,6 @@
/* PR tree-optimization/55921 */
/* { dg-skip-if "Not enough registers" { "pdp11-*-*" } } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
typedef union
{
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70240.c b/gcc/testsuite/gcc.c-torture/compile/pr70240.c
index 830d4ddcc93..466d3a7c961 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr70240.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr70240.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
typedef short v16hi __attribute__ ((vector_size (32)));
typedef int v8si __attribute__ ((vector_size (32)));
typedef long long v4di __attribute__ ((vector_size (32)));
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70355.c b/gcc/testsuite/gcc.c-torture/compile/pr70355.c
index 474942715f8..f7114208005 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr70355.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr70355.c
@@ -1,5 +1,7 @@
/* { dg-require-effective-target int128 } */
/* { dg-additional-options "-g" } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
typedef unsigned __int128 v2ti __attribute__ ((vector_size (32)));
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr82052.c b/gcc/testsuite/gcc.c-torture/compile/pr82052.c
index 3763161e350..09fac5edb1e 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr82052.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr82052.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned uint32_t;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr83487.c b/gcc/testsuite/gcc.c-torture/compile/pr83487.c
index 9effb1eef03..9de0e17939f 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr83487.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr83487.c
@@ -1,4 +1,5 @@
/* PR middle-end/83487 */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
struct __attribute__ ((aligned)) A {};
struct A a;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr86122.c b/gcc/testsuite/gcc.c-torture/compile/pr86122.c
index 0a4fd144ae6..1bd46733183 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr86122.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr86122.c
@@ -1,4 +1,5 @@
/* PR middle-end/86122 */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
_Complex int
foo (_Complex int x)
diff --git a/gcc/testsuite/gcc.c-torture/compile/pret-arg.c b/gcc/testsuite/gcc.c-torture/compile/pret-arg.c
index a7fa8562830..d86d135dc4b 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pret-arg.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pret-arg.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
foo (a, b, c, d, e, f, g, h, i, j, xx)
double xx;
{
diff --git a/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c b/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c
index f5f01116eda..77518866d3f 100644
--- a/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c
+++ b/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
+
int foo;
typedef long unsigned int size_t;
typedef short unsigned int wchar_t;
diff --git a/gcc/testsuite/gcc.c-torture/compile/structret.c b/gcc/testsuite/gcc.c-torture/compile/structret.c
index 9c705d4c0a2..d99eaa630bb 100644
--- a/gcc/testsuite/gcc.c-torture/compile/structret.c
+++ b/gcc/testsuite/gcc.c-torture/compile/structret.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
struct foo
{
int a, b, c, d;
diff --git a/gcc/testsuite/gcc.c-torture/compile/uuarg.c b/gcc/testsuite/gcc.c-torture/compile/uuarg.c
index 930dd8ab5f6..875c7c3b50f 100644
--- a/gcc/testsuite/gcc.c-torture/compile/uuarg.c
+++ b/gcc/testsuite/gcc.c-torture/compile/uuarg.c
@@ -1,4 +1,6 @@
/* { dg-require-effective-target untyped_assembly } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
+
foo (a, b, c, d, e, f, g, h, i)
{
return foo () + i;
diff --git a/gcc/testsuite/gcc.dg/20001009-1.c b/gcc/testsuite/gcc.dg/20001009-1.c
index 1a5567779b5..580e4b4d307 100644
--- a/gcc/testsuite/gcc.dg/20001009-1.c
+++ b/gcc/testsuite/gcc.dg/20001009-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target fpic } } */
/* { dg-options "-O2 -fpic" } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
extern void foo (void *a, double x, double y);
void
diff --git a/gcc/testsuite/gcc.dg/20020418-1.c b/gcc/testsuite/gcc.dg/20020418-1.c
index 7314ec000ef..456967fdd36 100644
--- a/gcc/testsuite/gcc.dg/20020418-1.c
+++ b/gcc/testsuite/gcc.dg/20020418-1.c
@@ -2,6 +2,7 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-options "-O2 -msse -ffast-math" { target i?86-*-* x86_64-*-* } } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
void bar (float *a, float *b);
diff --git a/gcc/testsuite/gcc.dg/20020426-2.c b/gcc/testsuite/gcc.dg/20020426-2.c
index 9ad7a54f601..96517f7b840 100644
--- a/gcc/testsuite/gcc.dg/20020426-2.c
+++ b/gcc/testsuite/gcc.dg/20020426-2.c
@@ -3,6 +3,7 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
/* { dg-options "-O2 -frename-registers -fomit-frame-pointer -fPIC -mtune=i686" { target { { i?86-*-* x86_64-*-* } && { ia32 && fpic } } } } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
extern void exit (int);
diff --git a/gcc/testsuite/gcc.dg/20020430-1.c b/gcc/testsuite/gcc.dg/20020430-1.c
index 63915a24b17..f48bb672aaf 100644
--- a/gcc/testsuite/gcc.dg/20020430-1.c
+++ b/gcc/testsuite/gcc.dg/20020430-1.c
@@ -6,6 +6,7 @@
/* { dg-do compile { target fpic } } */
/* { dg-options "-O2 -frename-registers -fpic" } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef unsigned long XID;
typedef XID Window;
diff --git a/gcc/testsuite/gcc.dg/20040306-1.c b/gcc/testsuite/gcc.dg/20040306-1.c
index 903d20ac256..8cac8697d99 100644
--- a/gcc/testsuite/gcc.dg/20040306-1.c
+++ b/gcc/testsuite/gcc.dg/20040306-1.c
@@ -2,7 +2,7 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
-
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef struct test
{
diff --git a/gcc/testsuite/gcc.dg/20040622-2.c b/gcc/testsuite/gcc.dg/20040622-2.c
index 0be320fa4e2..e62ec36d43a 100644
--- a/gcc/testsuite/gcc.dg/20040622-2.c
+++ b/gcc/testsuite/gcc.dg/20040622-2.c
@@ -1,5 +1,6 @@
/* { dg-do link } */
/* { dg-require-effective-target ptr32plus } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
/* This validates codegen for [r1+32760] on Darwin. */
void f(char x[32688], double *y, double *z) __attribute__((noinline));
void f(char x[32688], double *y, double *z) {}
diff --git a/gcc/testsuite/gcc.dg/20050603-2.c b/gcc/testsuite/gcc.dg/20050603-2.c
index 8c8e58e1b4d..a135e3ea1a0 100644
--- a/gcc/testsuite/gcc.dg/20050603-2.c
+++ b/gcc/testsuite/gcc.dg/20050603-2.c
@@ -1,5 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
+/* { dg-skip-if "no stdlib.h in eBPF" { bpf-*-* } } */
#include <stdlib.h>
struct s {
unsigned short f: 16;
diff --git a/gcc/testsuite/gcc.dg/20050629-1.c b/gcc/testsuite/gcc.dg/20050629-1.c
index 0dd47f7024b..99d9ce823b0 100644
--- a/gcc/testsuite/gcc.dg/20050629-1.c
+++ b/gcc/testsuite/gcc.dg/20050629-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O2 -w" } */
+/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
/* This file was automatically reduced from tree-ssa-operands.c. It
contains many warnings, but it exposes a copy propagation bug that
diff --git a/gcc/testsuite/gcc.dg/20061026.c b/gcc/testsuite/gcc.dg/20061026.c
index 741ea2eb3b8..fa8069ce4cf 100644
--- a/gcc/testsuite/gcc.dg/20061026.c
+++ b/gcc/testsuite/gcc.dg/20061026.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O1" } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
/* This testcase failed on s390. The frame size for function f will be
exactly 32768 bytes. The back end has to recognize that this is to
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-3.c
index 773f4633dc7..f119502f025 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-3.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-3.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O2 -Warray-bounds" } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
/* based on PR 31227 */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-30.c b/gcc/testsuite/gcc.dg/Warray-bounds-30.c
index ac7e9a6e8fb..b9965682101 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-30.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-30.c
@@ -1,7 +1,8 @@
/* PR tree-optimization/84047 - missing -Warray-bounds on an out-of-bounds
index into an array
{ dg-do compile }
- { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" } */
+ { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" }
+ { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
#include "range.h"
diff --git a/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c b/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c
index 1a5402f8120..d7068d04aef 100644
--- a/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c
+++ b/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c
@@ -1,6 +1,7 @@
/* Exercise -Wframe-larger-than= with a byte-size suffix.
{ dg-do compile }
- { dg-options "-O -Wframe-larger-than=1KB" } */
+ { dg-options "-O -Wframe-larger-than=1KB" }
+ { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
extern void f (void*, ...);
diff --git a/gcc/testsuite/gcc.dg/Wframe-larger-than.c b/gcc/testsuite/gcc.dg/Wframe-larger-than.c
index fab0adf37ee..8a40cf36df8 100644
--- a/gcc/testsuite/gcc.dg/Wframe-larger-than.c
+++ b/gcc/testsuite/gcc.dg/Wframe-larger-than.c
@@ -4,6 +4,7 @@
/* { dg-do compile } */
/* { dg-options "-Wframe-larger-than=2048" } */
+/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */
extern void func(char *);
diff --git a/gcc/testsuite/gcc.dg/Wrestrict-11.c b/gcc/testsuite/gcc.dg/Wrestrict-11.c
index 7b4b5aa2527..07b9cddad4b 100644
--- a/gcc/testsuite/gcc.dg/Wrestrict-11.c
+++ b/gcc/testsuite/gcc.dg/Wrestrict-11.c
@@ -3,7 +3,8 @@
that calls to strncpy involving multidimensional arrays of structs don't
trigger false positive -Wrestrict warnings.
{ dg-do compile }
- { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } */
+ { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" }
+ { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/builtins-config.h b/gcc/testsuite/gcc.dg/builtins-config.h
index f00e91a750f..5e27c1deb33 100644
--- a/gcc/testsuite/gcc.dg/builtins-config.h
+++ b/gcc/testsuite/gcc.dg/builtins-config.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2009, 2011, 2012
+/* Copyright (C) 2003, 2004, 2005, 2006, 2009, 2011, 2012, 2019
Free Software Foundation.
Define macros useful in tests for bulitin functions. */
@@ -20,6 +20,8 @@
/* FreeBSD up to version 8 lacks support for cexp and friends. */
#elif defined(__vxworks)
/* VxWorks doesn't have a full C99 time. (cabs is missing, for example.) */
+#elif defined (__BPF__)
+/* No chance for eBPF to support C99 functions. */
#elif defined(_WIN32) && !defined(__CYGWIN__)
/* Windows doesn't have the entire C99 runtime. */
#elif (defined(__APPLE__) && defined(__ppc__) \
--
2.11.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH V4 05/11] bpf: new GCC port
2019-08-27 23:51 [PATCH V4 00/11] eBPF support for GCC Jose E. Marchesi
` (9 preceding siblings ...)
2019-08-28 0:43 ` [PATCH V4 09/11] bpf: adjust GCC testsuite to eBPF limitations Jose E. Marchesi
@ 2019-08-28 1:18 ` Jose E. Marchesi
2019-08-28 15:44 ` Jose E. Marchesi
2019-08-28 1:53 ` [PATCH V4 00/11] eBPF support for GCC Jose E. Marchesi
2019-08-28 9:02 ` Richard Sandiford
12 siblings, 1 reply; 18+ messages in thread
From: Jose E. Marchesi @ 2019-08-28 1:18 UTC (permalink / raw)
To: Jose E. Marchesi; +Cc: gcc-patches
This patch adds a port for the Linux kernel eBPF architecture to GCC.
ChangeLog:
* configure.ac: Support for bpf-*-* targets.
* configure: Regenerate.
contrib/ChangeLog:
* config-list.mk (LIST): Disable go in bpf-*-* targets.
gcc/ChangeLog:
* 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.
---
ChangeLog | 5 +
configure | 54 ++-
configure.ac | 54 ++-
contrib/ChangeLog | 4 +
contrib/config-list.mk | 3 +-
gcc/ChangeLog | 16 +
gcc/common/config/bpf/bpf-common.c | 55 +++
gcc/config.gcc | 9 +
gcc/config/bpf/bpf-helpers.def | 194 ++++++++
gcc/config/bpf/bpf-helpers.h | 327 +++++++++++++
gcc/config/bpf/bpf-opts.h | 56 +++
gcc/config/bpf/bpf-protos.h | 33 ++
gcc/config/bpf/bpf.c | 958 +++++++++++++++++++++++++++++++++++++
gcc/config/bpf/bpf.h | 532 ++++++++++++++++++++
gcc/config/bpf/bpf.md | 497 +++++++++++++++++++
gcc/config/bpf/bpf.opt | 123 +++++
gcc/config/bpf/constraints.md | 32 ++
gcc/config/bpf/predicates.md | 72 +++
gcc/config/bpf/t-bpf | 0
19 files changed, 3021 insertions(+), 3 deletions(-)
create mode 100644 gcc/common/config/bpf/bpf-common.c
create mode 100644 gcc/config/bpf/bpf-helpers.def
create mode 100644 gcc/config/bpf/bpf-helpers.h
create mode 100644 gcc/config/bpf/bpf-opts.h
create mode 100644 gcc/config/bpf/bpf-protos.h
create mode 100644 gcc/config/bpf/bpf.c
create mode 100644 gcc/config/bpf/bpf.h
create mode 100644 gcc/config/bpf/bpf.md
create mode 100644 gcc/config/bpf/bpf.opt
create mode 100644 gcc/config/bpf/constraints.md
create mode 100644 gcc/config/bpf/predicates.md
create mode 100644 gcc/config/bpf/t-bpf
diff --git a/configure.ac b/configure.ac
index 1fe97c001cc..b8ce2ad20b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -638,6 +638,9 @@ case "${target}" in
# No hosted I/O support.
noconfigdirs="$noconfigdirs target-libssp"
;;
+ bpf-*-*)
+ noconfigdirs="$noconfigdirs target-libssp"
+ ;;
powerpc-*-aix* | rs6000-*-aix*)
noconfigdirs="$noconfigdirs target-libssp"
;;
@@ -672,12 +675,43 @@ if test "${ENABLE_LIBSTDCXX}" = "default" ; then
avr-*-*)
noconfigdirs="$noconfigdirs target-libstdc++-v3"
;;
+ bpf-*-*)
+ noconfigdirs="$noconfigdirs target-libstdc++-v3"
+ ;;
ft32-*-*)
noconfigdirs="$noconfigdirs target-libstdc++-v3"
;;
esac
fi
+# Disable C++ on systems where it is known to not work.
+# For testing, you can override this with --enable-languages=c++.
+case ,${enable_languages}, in
+ *,c++,*)
+ ;;
+ *)
+ case "${target}" in
+ bpf-*-*)
+ unsupported_languages="$unsupported_languages c++"
+ ;;
+ esac
+ ;;
+esac
+
+# Disable Objc on systems where it is known to not work.
+# For testing, you can override this with --enable-languages=objc.
+case ,${enable_languages}, in
+ *,objc,*)
+ ;;
+ *)
+ case "${target}" in
+ bpf-*-*)
+ unsupported_languages="$unsupported_languages objc"
+ ;;
+ esac
+ ;;
+esac
+
# Disable D on systems where it is known to not work.
# For testing, you can override this with --enable-languages=d.
case ,${enable_languages}, in
@@ -687,6 +721,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"
;;
diff --git a/contrib/config-list.mk b/contrib/config-list.mk
index 69c826e649a..61e38bf0e50 100644
--- a/contrib/config-list.mk
+++ b/contrib/config-list.mk
@@ -40,6 +40,7 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \
arm-linux-androideabi arm-uclinux_eabi arm-eabi arm-rtems \
arm-symbianelf avr-elf \
bfin-elf bfin-uclinux bfin-linux-uclibc bfin-rtems bfin-openbsd \
+ bpf-unknown-none \
c6x-elf c6x-uclinux cr16-elf cris-elf cris-linux crisv32-elf crisv32-linux \
csky-elf csky-linux-gnu \
epiphany-elf epiphany-elfOPT-with-stack-offset=16 fido-elf \
@@ -123,7 +124,7 @@ $(LIST): make-log-dir
TGT=`echo $@ | awk 'BEGIN { FS = "OPT" }; { print $$1 }'` && \
TGT=`$(GCC_SRC_DIR)/config.sub $$TGT` && \
case $$TGT in \
- *-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix*) \
+ *-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix* | bpf-*-*) \
ADDITIONAL_LANGUAGES=""; \
;; \
*) \
diff --git a/gcc/common/config/bpf/bpf-common.c b/gcc/common/config/bpf/bpf-common.c
new file mode 100644
index 00000000000..0d04f21b8f9
--- /dev/null
+++ b/gcc/common/config/bpf/bpf-common.c
@@ -0,0 +1,55 @@
+/* Common hooks for eBPF.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<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;
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 11a8ac73e12..b579aa09bc4 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -360,6 +360,9 @@ avr-*-*)
bfin*-*)
cpu_type=bfin
;;
+bpf-*-*)
+ cpu_type=bpf
+ ;;
crisv32-*)
cpu_type=cris
;;
@@ -1311,6 +1314,12 @@ bfin*-*)
use_collect2=no
use_gcc_stdint=wrap
;;
+bpf-*-*)
+ tmake_file="${tmake_file} bpf/t-bpf"
+ use_collect2=no
+ extra_headers="bpf-helpers.h"
+ use_gcc_stdint=provide
+ ;;
cr16-*-elf)
tm_file="elfos.h ${tm_file} newlib-stdint.h"
tmake_file="${tmake_file} cr16/t-cr16 "
diff --git a/gcc/config/bpf/bpf-helpers.def b/gcc/config/bpf/bpf-helpers.def
new file mode 100644
index 00000000000..7330498a9e7
--- /dev/null
+++ b/gcc/config/bpf/bpf-helpers.def
@@ -0,0 +1,194 @@
+/* Kernel helpers database.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<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, pt, 0))
+DEF_HELPER (LINUX_V4_8, PROBE_WRITE_USER, probe_write_user, TYPES (it, pt, cpt, ut, 0))
+DEF_HELPER (LINUX_V4_9, CURRENT_TASK_UNDER_CGROUP, current_task_under_cgroup, \
+ TYPES (it, pt, it, 0))
+DEF_HELPER (LINUX_V4_9, SKB_CHANGE_TAIL, skb_change_tail, TYPES (it, pt, ut, u64t, 0))
+DEF_HELPER (LINUX_V4_9, SKB_PULL_DATA, skb_pull_data, TYPES (it, pt, it, 0))
+DEF_HELPER (LINUX_V4_9, CSUM_UPDATE, csum_update, TYPES (llt, pt, u32t, 0))
+DEF_HELPER (LINUX_V4_9, SET_HASH_INVALID, set_hash_invalid, TYPES (vt, pt, 0))
+DEF_HELPER (LINUX_V4_10, GET_NUMA_NODE_ID, get_numa_node_id, TYPES (it, 0))
+DEF_HELPER (LINUX_V4_10, SKB_CHANGE_HEAD, skb_change_head, TYPES (it, pt, it, it, 0))
+DEF_HELPER (LINUX_V4_10, XDP_ADJUST_HEAD, xdp_adjust_head, TYPES (it, pt, it, 0))
+DEF_HELPER (LINUX_V4_11, PROBE_READ_STR, probe_read_str, TYPES (it, pt, u32t, cpt, 0))
+DEF_HELPER (LINUX_V4_12, GET_SOCKET_COOKIE, get_socket_cookie, TYPES (it, pt, 0))
+DEF_HELPER (LINUX_V4_12, GET_SOCKET_UID, get_socket_uid, TYPES (ut, pt, 0))
+DEF_HELPER (LINUX_V4_13, SET_HASH, set_hash, TYPES (ut, pt, u32t, 0))
+DEF_HELPER (LINUX_V4_13, SETSOCKOPT, setsockopt, TYPES (it, pt, it, it, pt, it, 0))
+DEF_HELPER (LINUX_V4_13, SKB_ADJUST_ROOM, skb_adjust_room, TYPES (it, pt, st, u32t, ullt, 0))
+DEF_HELPER (LINUX_V4_14, REDIRECT_MAP, redirect_map, TYPES (it, pt, it, it, 0))
+DEF_HELPER (LINUX_V4_14, SK_REDIRECT_MAP, sk_redirect_map, TYPES (it, pt, pt, it, it, 0))
+DEF_HELPER (LINUX_V4_14, SOCK_MAP_UPDATE, sock_map_update, TYPES (it, pt, pt, pt, ullt, 0))
+DEF_HELPER (LINUX_V4_15, XDP_ADJUST_META, xdp_adjust_meta, TYPES (it, pt, it, 0))
+DEF_HELPER (LINUX_V4_15, PERF_EVENT_READ_VALUE, perf_event_read_value,
+ TYPES (it, pt, ullt, pt, ut, 0))
+DEF_HELPER (LINUX_V4_15, PERF_PROG_READ_VALUE, perf_prog_read_value,
+ TYPES (it, pt, pt, ut, 0))
+DEF_HELPER (LINUX_V4_15, GETSOCKOPT, getsockopt, TYPES (it, pt, it, it, pt, it, 0))
+
+DEF_HELPER (LINUX_V4_16, OVERRIDE_RETURN, override_return, TYPES (it, pt, ult, 0))
+DEF_HELPER (LINUX_V4_16, SOCK_OPS_CB_FLAGS_SET, sock_ops_cb_flags_set, TYPES (it, pt, it, 0))
+DEF_HELPER (LINUX_V4_17, MSG_REDIRECT_MAP, msg_redirect_map, TYPES (it, pt, pt, it, it, 0))
+DEF_HELPER (LINUX_V4_17, MSG_APPLY_BYTES, msg_apply_bytes, TYPES (it, pt, it, 0))
+DEF_HELPER (LINUX_V4_17, MSG_CORK_BYTES, msg_cork_bytes, TYPES (it, pt, it, 0))
+DEF_HELPER (LINUX_V4_17, MSG_PULL_DATA, msg_pull_data, TYPES (it, pt, it, it, it, 0))
+DEF_HELPER (LINUX_V4_17, BIND, bind, TYPES (it, pt, pt, it, 0))
+DEF_HELPER (LINUX_V4_18, XDP_ADJUST_TAIL, xdp_adjust_tail, TYPES (it, pt, it, 0))
+DEF_HELPER (LINUX_V4_18, SKB_GET_XFRM_STATE,
+ skb_get_xfrm_state, TYPES (it, pt, it, pt, it, it, 0))
+DEF_HELPER (LINUX_V4_18, GET_STACK, get_stack, TYPES (it, pt, pt, it, it, 0))
+DEF_HELPER (LINUX_V4_18, SKB_LOAD_BYTES_RELATIVE, skb_load_bytes_relative,
+ TYPES (it, pt, it, pt, it, ut, 0))
+DEF_HELPER (LINUX_V4_18, FIB_LOOKUP, fib_lookup, TYPES (it, pt, pt, it, ut, 0))
+DEF_HELPER (LINUX_V4_18, SOCK_HASH_UPDATE, sock_hash_update, TYPES (it, pt, pt, pt, ullt, 0))
+DEF_HELPER (LINUX_V4_18, MSG_REDIRECT_HASH, msg_redirect_hash, TYPES (it, pt, pt, pt, it, 0))
+DEF_HELPER (LINUX_V4_18, SK_REDIRECT_HASH, sk_redirect_hash, TYPES (it, pt, pt, pt, it, 0))
+DEF_HELPER (LINUX_V4_18, LWT_PUSH_ENCAP, lwt_push_encap, TYPES (it, pt, ut, pt, ut, 0))
+DEF_HELPER (LINUX_V4_18, LWT_SEG6_STORE_BYTES, lwt_seg6_store_bytes,
+ TYPES (it, pt, ut, pt, ut, 0))
+DEF_HELPER (LINUX_V4_18, LWT_SEG6_ADJUST_SRH, lwt_seg6_adjust_srh, TYPES (it, pt, ut, ut, 0))
+DEF_HELPER (LINUX_V4_18, LWT_SEG6_ACTION, lwt_seg6_action, TYPES (it, pt, ut, pt, ut, 0))
+DEF_HELPER (LINUX_V4_18, RC_REPEAT, rc_repeat, TYPES (it, pt, 0))
+DEF_HELPER (LINUX_V4_18, RC_KEYDOWN, rc_keydown, TYPES (it, pt, ut, ullt, ut, 0))
+DEF_HELPER (LINUX_V4_18, SKB_CGROUP_ID, skb_cgroup_id, TYPES (ullt, pt, 0))
+DEF_HELPER (LINUX_V4_18, GET_CURRENT_CGROUP_ID, get_current_cgroup_id, TYPES (ullt, 0))
+DEF_HELPER (LINUX_V4_19, GET_LOCAL_STORAGE, get_local_storage, TYPES (pt, pt, ullt, 0))
+DEF_HELPER (LINUX_V4_19, SK_SELECT_REUSEPORT, sk_select_reuseport,
+ TYPES (it, pt, pt, pt, ut, 0))
+DEF_HELPER (LINUX_V4_19, SKB_ANCESTOR_CGROUP_ID, skb_ancestor_cgroup_id,
+ TYPES (ullt, pt, it, 0))
+DEF_HELPER (LINUX_V4_20, SK_LOOKUP_TCP, sk_lookup_tcp, TYPES (pt, pt, pt, it, ullt, ullt, 0))
+DEF_HELPER (LINUX_V4_20, SK_LOOKUP_UDP, sk_lookup_udp, TYPES (pt, pt, pt, it, ullt, ullt, 0))
+DEF_HELPER (LINUX_V4_20, SK_RELEASE, sk_release, TYPES (it, pt, 0))
+DEF_HELPER (LINUX_V4_20, MAP_PUSH_ELEM, map_push_elem, TYPES (it, pt, pt, ullt, 0))
+DEF_HELPER (LINUX_V4_20, MAP_POP_ELEM, map_pop_elem, TYPES (it, pt, pt, 0))
+DEF_HELPER (LINUX_V4_20, MAP_PEEK_ELEM, map_peek_elem, TYPES (it, pt, pt, 0))
+DEF_HELPER (LINUX_V4_20, MSG_PUSH_DATA, msg_push_data, TYPES (it, pt, it, it, it, 0))
+DEF_HELPER (LINUX_V5_0, MSG_POP_DATA, msg_pop_data, TYPES (it, pt, it, it, it, 0))
+DEF_HELPER (LINUX_V5_0, RC_POINTER_REL, rc_pointer_rel, TYPES (it, pt, it, it, 0))
+DEF_HELPER (LINUX_V5_1, SPIN_LOCK, spin_lock, TYPES (vt, pt, 0))
+DEF_HELPER (LINUX_V5_1, SPIN_UNLOCK, spin_unlock, TYPES (vt, pt, 0))
+DEF_HELPER (LINUX_V5_1, SK_FULLSOCK, sk_fullsock, TYPES (pt, pt, 0))
+DEF_HELPER (LINUX_V5_1, TCP_SOCK, tcp_sock, TYPES (pt, pt, 0))
+DEF_HELPER (LINUX_V5_1, SKB_ECN_SET_CE, skb_ecn_set_ce, TYPES (it, pt, 0))
+DEF_HELPER (LINUX_V5_1, GET_LISTENER_SOCK, get_listener_sock, TYPES (pt, pt, 0))
+DEF_HELPER (LINUX_V5_2, SKC_LOOKUP_TCP, skc_lookup_tcp,
+ TYPES (pt, pt, pt, u32t, u64t, u64t, 0))
+DEF_HELPER (LINUX_V5_2, TCP_CHECK_SYNCOOKIE, tcp_check_syncookie,
+ TYPES (it, pt, pt, u32t, pt, u32t, 0))
+DEF_HELPER (LINUX_V5_2, SYSCTL_GET_NAME, sysctl_get_name, TYPES (it, pt, pt, ullt, u64t, 0))
+DEF_HELPER (LINUX_V5_2, SYSCTL_GET_CURRENT_VALUE, sysctl_get_current_value,
+ TYPES (it, pt, pt, ullt, 0))
+DEF_HELPER (LINUX_V5_2, SYSCTL_GET_NEW_VALUE, sysctl_get_new_value,
+ TYPES (it, pt, pt, ullt, 0))
+DEF_HELPER (LINUX_V5_2, SYSCTL_SET_NEW_VALUE, sysctl_set_new_value,
+ TYPES (it, pt, pt, ullt, 0))
+DEF_HELPER (LINUX_V5_2, STRTOL, strtol, TYPES (it, cst, ullt, u64t, pt, 0))
+DEF_HELPER (LINUX_V5_2, STRTOUL, strtoul, TYPES (it, pt, ullt, u64t, pt, 0))
+DEF_HELPER (LINUX_V5_2, SK_STORAGE_GET, sk_storage_get, TYPES (pt, pt, pt, pt, u64t, 0))
+DEF_HELPER (LINUX_V5_2, SK_STORAGE_DELETE, sk_storage_delete, TYPES (it, pt, pt, 0))
+
+/*
+Local variables:
+mode:c
+End:
+*/
diff --git a/gcc/config/bpf/bpf-helpers.h b/gcc/config/bpf/bpf-helpers.h
new file mode 100644
index 00000000000..14275439446
--- /dev/null
+++ b/gcc/config/bpf/bpf-helpers.h
@@ -0,0 +1,327 @@
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <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
index 00000000000..9f210a19c4a
--- /dev/null
+++ b/gcc/config/bpf/bpf-opts.h
@@ -0,0 +1,56 @@
+/* Definitions for option handling for eBPF.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <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
index 00000000000..3a835f4f12e
--- /dev/null
+++ b/gcc/config/bpf/bpf-protos.h
@@ -0,0 +1,33 @@
+/* Definition of eBPF target for GNU compiler.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<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
index 00000000000..853c9222a5d
--- /dev/null
+++ b/gcc/config/bpf/bpf.c
@@ -0,0 +1,958 @@
+/* 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_LITTLE_ENDIAN)
+ builtin_define ("__BPF_LITTLE_ENDIAN__");
+ else
+ builtin_define ("__BPF_BIG_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)
+{
+ poly_int64 mode_size = GET_MODE_SIZE (arg.mode);
+ unsigned num_bytes
+ = (arg.type ? arg.type_size_in_bytes() : mode_size);
+
+ /* Pass aggregates and values bigger than 5 words by reference.
+ Everything else is passed by copy. */
+ return ((arg.type && 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);
+ poly_int64 mode_size = GET_MODE_SIZE (arg.mode);
+ unsigned num_bytes = (arg.type
+ ? arg.type_size_in_bytes () : mode_size);
+ unsigned num_words
+ = CEIL (num_bytes, UNITS_PER_WORD);
+
+ if (*cum <= 5 && *cum + num_words > 5)
+ error ("too many function arguments for eBPF");
+ else
+ *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 a 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) == LABEL_REF
+ || GET_CODE (op1) == SYMBOL_REF
+ || GET_CODE (op1) == CONST_INT
+ || GET_CODE (op1) == CONST))
+ {
+ fprintf (file, "[%s+", reg_names[REGNO (op0)]);
+ output_addr_const (file, op1);
+ fputs ("]", file);
+ }
+ else
+ fatal_insn ("invalid address in operand", addr);
+ break;
+ }
+ case MEM:
+ /* Fallthrough. */
+ case LABEL_REF:
+ /* Fallthrough. */
+ fatal_insn ("unsupported operand", addr);
+ break;
+ default:
+ output_addr_const (file, addr);
+ break;
+ }
+}
+
+/* Add a BPF builtin function with NAME, CODE and TYPE. Return
+ the function decl or NULL_TREE if the builtin was not added. */
+
+static tree
+def_builtin (const char *name, enum bpf_builtins code, tree type)
+{
+ tree t
+ = add_builtin_function (name, type, code, BUILT_IN_MD, NULL, NULL_TREE);
+
+ bpf_builtins[code] = t;
+ return t;
+}
+
+/* Define machine-specific built-in functions. */
+
+static void
+bpf_init_builtins (void)
+{
+ /* Built-ins for calling kernel helpers. */
+
+ tree pt = build_pointer_type (void_type_node);
+ tree const_void_type
+ = build_qualified_type (void_type_node, TYPE_QUAL_CONST);
+ tree cpt = build_pointer_type (const_void_type);
+ tree st = short_integer_type_node;
+ tree ust = uint16_type_node;
+ tree it = integer_type_node;
+ tree ut = unsigned_type_node;
+ tree const_char_type
+ = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
+ tree cst = build_pointer_type (const_char_type);
+ tree vt = void_type_node;
+ tree ult = long_unsigned_type_node;
+ tree u32t = uint32_type_node;
+ tree u64t = uint64_type_node;
+ tree llt = long_long_integer_type_node;
+ tree ullt = long_long_unsigned_type_node;
+
+#define TYPES build_function_type_list
+#define VTYPES build_varargs_function_type_list
+#define DEF_HELPER(V,D,N,T) \
+ do \
+ { \
+ if (bpf_kernel >= (V)) \
+ def_builtin ("__builtin_bpf_helper_" #N, \
+ BPF_BUILTIN_HELPER_##D, \
+ T); \
+ } while (0);
+# include "bpf-helpers.def"
+#undef TYPES
+#undef VTYPES
+#undef DEF_HELPER
+
+ /* Built-ins for BPF_LD_ABS and BPF_LD_IND instructions. */
+
+ def_builtin ("__builtin_bpf_load_byte", BPF_BUILTIN_LOAD_BYTE,
+ build_function_type_list (ullt, ullt, 0));
+ def_builtin ("__builtin_bpf_load_half", BPF_BUILTIN_LOAD_HALF,
+ build_function_type_list (ullt, ullt, 0));
+ def_builtin ("__builtin_bpf_load_word", BPF_BUILTIN_LOAD_WORD,
+ build_function_type_list (ullt, ullt, 0));
+}
+
+#undef TARGET_INIT_BUILTINS
+#define TARGET_INIT_BUILTINS bpf_init_builtins
+
+/* Expand a call to a BPF-specific built-in function that was set up
+ with bpf_init_builtins. */
+
+static rtx
+bpf_expand_builtin (tree exp, rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore)
+{
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ int code = DECL_MD_FUNCTION_CODE (fndecl);
+
+ if (code >= 1 && code < BPF_BUILTIN_HELPER_MAX)
+ {
+ /* This is a builtin to call a kernel helper function.
+
+ For these builtins, we just expand the function call normally
+ with expand_call like we would do for a libcall. The function
+ bpf_output_call below will then do The Right Thing (TM),
+ recognizing the name of the called __builtin_helper_* symbol
+ and emitting the corresponding CALL N instruction whenever
+ necessary. */
+
+ return expand_call (exp, target, ignore);
+ }
+ else if (code == BPF_BUILTIN_LOAD_BYTE
+ || code == BPF_BUILTIN_LOAD_HALF
+ || code == BPF_BUILTIN_LOAD_WORD)
+ {
+ /* Expand an indirect load from the sk_buff in the context.
+ There is just one argument to the builtin, which is the
+ offset.
+
+ We try first to expand a ldabs* instruction. In case this
+ fails, we try a ldind* instruction. */
+
+ enum insn_code abs_icode
+ = (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldabsb
+ : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldabsh
+ : CODE_FOR_ldabsw);
+
+ enum insn_code ind_icode
+ = (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldindb
+ : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldindh
+ : CODE_FOR_ldindw);
+
+ tree offset_arg = CALL_EXPR_ARG (exp, 0);
+ struct expand_operand ops[2];
+
+ create_input_operand (&ops[0], expand_normal (offset_arg),
+ TYPE_MODE (TREE_TYPE (offset_arg)));
+ create_input_operand (&ops[1], const0_rtx, SImode);
+
+ if (!maybe_expand_insn (abs_icode, 2, ops)
+ && !maybe_expand_insn (ind_icode, 2, ops))
+ {
+ error ("invalid argument to built-in function");
+ return gen_rtx_REG (ops[0].mode, BPF_R0);
+ }
+
+ /* The result of the load is in R0. */
+ return gen_rtx_REG (ops[0].mode, BPF_R0);
+ }
+
+ gcc_unreachable ();
+}
+
+#undef TARGET_EXPAND_BUILTIN
+#define TARGET_EXPAND_BUILTIN bpf_expand_builtin
+
+/* Initialize target-specific function library calls. This is mainly
+ used to call library-provided soft-fp operations, since eBPF
+ doesn't support floating-point in "hardware". */
+
+static void
+bpf_init_libfuncs (void)
+{
+ set_conv_libfunc (sext_optab, DFmode, SFmode,
+ "__bpf_extendsfdf2");
+ set_conv_libfunc (trunc_optab, SFmode, DFmode,
+ "__bpf_truncdfsf2");
+ set_conv_libfunc (sfix_optab, SImode, DFmode,
+ "__bpf_fix_truncdfsi");
+ set_conv_libfunc (sfloat_optab, DFmode, SImode,
+ "__bpf_floatsidf");
+ set_conv_libfunc (ufloat_optab, DFmode, SImode,
+ "__bpf_floatunsidf");
+}
+
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS bpf_init_libfuncs
+
+/* Define the mechanism that will be used for describing frame unwind
+ information to the debugger. In eBPF it is not possible to unwind
+ frames. */
+
+static enum unwind_info_type
+bpf_debug_unwind_info ()
+{
+ return UI_NONE;
+}
+
+#undef TARGET_DEBUG_UNWIND_INFO
+#define TARGET_DEBUG_UNWIND_INFO bpf_debug_unwind_info
+
+/* Output assembly directives to assemble data of various sized and
+ alignments. */
+
+#undef TARGET_ASM_BYTE_OP
+#define TARGET_ASM_BYTE_OP "\t.byte\t"
+#undef TARGET_ASM_ALIGNED_HI_OP
+#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
+#undef TARGET_ASM_ALIGNED_SI_OP
+#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
+#undef TARGET_ASM_ALIGNED_DI_OP
+#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
+
+/* Finally, build the GCC target. */
+
+struct gcc_target targetm = TARGET_INITIALIZER;
+
+#include "gt-bpf.h"
diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
new file mode 100644
index 00000000000..09c8c0583dc
--- /dev/null
+++ b/gcc/config/bpf/bpf.h
@@ -0,0 +1,532 @@
+/* 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} %{mlittle-endian:-EL}"
+#define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-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_LITTLE_ENDIAN)
+#define WORDS_BIG_ENDIAN (!TARGET_LITTLE_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 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. */
+ GENERAL_REGS, /* general-purpose integer registers. */
+ ALL_REGS, /* all registers. */
+ LIM_REG_CLASSES /* max value + 1. */
+};
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* 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", \
+ "GENERAL_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 */ \
+ 0x000007ff, /* GENERAL_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
+ non-fake hard register can be used for this purpose. */
+#define REGNO_OK_FOR_BASE_P(REGNO) \
+ ((REGNO) < 11)
+
+/* C expression which is nonzero if register number REGNO is suitable
+ for use as an index register in operand addresses. */
+#define REGNO_OK_FOR_INDEX_P(REGNO) false
+
+/**** Debugging Info ****/
+
+/* We cannot support DWARF2 because of the limitations of eBPF. */
+#define DBX_DEBUGGING_INFO
+
+/**** Stack Layout and Calling Conventions. */
+
+/*** Basic Stack Layout. */
+
+#define STACK_GROWS_DOWNWARD 1
+#define FRAME_GROWS_DOWNWARD 1
+
+/* The argument pointer always points to the first argument. */
+#define FIRST_PARM_OFFSET(FNDECL) 0
+
+/* Unsupported. */
+#define RETURN_ADDR_RTX(count, frame) const0_rtx
+
+/*** Registers That Address the Stack Frame. */
+
+#define FRAME_POINTER_REGNUM 10
+#define STACK_POINTER_REGNUM 9
+#define ARG_POINTER_REGNUM 11
+#define STATIC_CHAIN_REGNUM 8
+
+/*** Registers elimination. */
+
+#define ELIMINABLE_REGS \
+ {{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }}
+
+/* Define the offset between two registers, one to be eliminated, and
+ the other its replacement, at the start of a routine. */
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ do \
+ { \
+ (OFFSET) = bpf_initial_elimination_offset ((FROM), (TO)); \
+ } while (0)
+
+/*** Passing Function Arguments on the Stack. */
+
+/* The eBPF ABI doesn't support passing arguments on the stack. Only
+ in the first five registers. Code in bpf.c assures the stack is
+ never used when passing arguments. However, we still have to
+ define the constants below. */
+
+/* If nonzero, push insns will be used to pass outgoing arguments. */
+#define PUSH_ARGS 0
+
+/* If nonzero, function arguments will be evaluated from last to
+ first, rather than from first to last. */
+#define PUSH_ARGS_REVERSED 1
+
+/* Allocate stack space for arguments at the beginning of each
+ function. */
+#define ACCUMULATE_OUTGOING_ARGS 1
+
+/*** Passing Arguments in Registers. */
+
+/* Use an integer in order to keep track of the number of arguments
+ passed to a function in integer registers, up to
+ MAX_ARGS_IN_REGISTERS. */
+#define CUMULATIVE_ARGS int
+
+/* INIT_CUMULATIVE_ARGS initializes a variable CUM of type
+ CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE.
+ For a library call, FNTYPE is 0. */
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \
+ memset (&(CUM), 0, sizeof (CUM))
+
+/* Nonzero if N is the number of a hard register in which function
+ arguments are sometimes passed. */
+#define FUNCTION_ARG_REGNO_P(N) ((N) >= 1 && (N) <= 5)
+
+/*** How Scalar Function Values are Returned. */
+
+/* Define how to find the value returned by a library function
+ assuming the value has mode MODE. This is always %r0 for eBPF. */
+#define LIBCALL_VALUE(MODE) \
+ gen_rtx_REG ((MODE), 0)
+
+/*** Generating Code for Profiling. */
+
+/* We do not support profiling yet, so do not call `mcount'. */
+#define FUNCTION_PROFILER(FILE, LABELNO) do { } while (0)
+
+/*** Function Entry and Exit. */
+
+/* We do not require an accurate stack pointer at function return.
+ This is because the stack pointer's original value is initialized
+ from the frame pointer, rather than decreased, to satisfy the
+ kernel's verifier. Thus, we have to save the stack pointer in
+ function prologue and restore it in function epilogue. If
+ EXIT_IGNORE_STACK is not set, then superfluous instructions are
+ generated to save and restore the stack pointer after and before
+ the function epilogue, respectively. */
+#define EXIT_IGNORE_STACK 1
+
+/**** Support for Nested Functions. */
+
+/* We have to define TRAMPOLINE_SIZE even if we don't ever generate
+ them. Set to 64 arbitrarily. */
+#define TRAMPOLINE_SIZE 64
+
+/**** Addressing Modes. */
+
+/* Maximum number of registers that can appear in a valid memory
+ address. */
+#define MAX_REGS_PER_ADDRESS 1
+
+/* 1 if X is an rtx for a constant that is a valid address. */
+
+#define CONSTANT_ADDRESS_P(X) 0
+
+/**** Describing Relative Costs of Operations. */
+
+/* Cost of a branch instruction. A value of 1 is the default. */
+#define BRANCH_COST(SPEED_P,PREDICTABLE_P) 1
+
+/* The SPARC port says: Nonzero if access to memory by bytes is slow
+ and undesirable. For RISC chips, it means that access to memory by
+ bytes is no better than access by words when possible, so grab a
+ whole word and maybe make use of that. */
+#define SLOW_BYTE_ACCESS 1
+
+/* Threshold of number of scalar memory-to-memory move instructions,
+ _below_ which a sequence of insns should be generated instead of a
+ string move insn or a library call. */
+#define MOVE_RATIO(speed) 128
+
+/* Threshold of number of scalar move instructions, _below_ which a
+ sequence of insns should be generated to clear memory instead of a
+ string clear insn or a library call. */
+#define CLEAR_RATIO(speed) 128
+
+/* Threshold of number of scalar move instructions, _below_ which a
+ sequence of insns should be generated to set memory to a constant
+ value, instead of a block set insn or a library call. */
+#define SET_RATIO(speed) 128
+
+/* True if it is as good or better to call a constant function address
+ than to call an address kept in a register. */
+#define NO_FUNCTION_CSE 1
+
+/**** Dividing the Output into Sections. */
+
+#define TEXT_SECTION_ASM_OP "\t.text"
+#define DATA_SECTION_ASM_OP "\t.data"
+#define BSS_SECTION_ASM_OP "\t.bss"
+#define COMMON_ASM_OP "\t.common\t"
+
+/**** Defining the Output Assembler Language. */
+
+/*** The Overall Framework of an Assembler File. */
+
+#define ASM_COMMENT_START ";"
+
+/* Output to assembler file text saying following lines
+ may contain character constants, extra white space, comments, etc. */
+
+#ifndef ASM_APP_ON
+#define ASM_APP_ON " #APP\n"
+#endif
+
+/* Output to assembler file text saying following lines
+ no longer contain unusual constructs. */
+
+#ifndef ASM_APP_OFF
+#define ASM_APP_OFF " #NO_APP\n"
+#endif
+
+/*** Output of Data. */
+
+/*** Output of Uninitialized Variables. */
+
+/* How to output an assembler line to define a local common
+ symbol. */
+
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+ do \
+ { \
+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ",%u,%u\n", (int)(SIZE), (ALIGN) / (BITS_PER_UNIT)); \
+ } \
+ while (0)
+
+/* A C statement (sans semicolon) to output to the stdio stream
+ FILE the assembler definition of uninitialized global DECL named
+ NAME whose size is SIZE bytes and alignment is ALIGN bytes.
+ Try to use asm_output_aligned_bss to implement this macro. */
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ do { \
+ ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
+ } while (0)
+
+/* This says how to output an assembler line to define a local common
+ symbol. */
+
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE,NAME,SIZE,ALIGN) \
+ ( fputs ("\t.lcomm ", (FILE)), \
+ assemble_name ((FILE), (NAME)), \
+ fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED "\n", \
+ (SIZE), ((ALIGN) / BITS_PER_UNIT)))
+
+/*** Output and Generation of Labels. */
+
+/* Globalizing directive for a label. */
+#define GLOBAL_ASM_OP "\t.global\t"
+
+/* This is how to store into the string LABEL
+ the symbol_ref name of an internal numbered label where
+ PREFIX is the class of label and NUM is the number within the class.
+ This is suitable for output with `assemble_name'. */
+
+#undef ASM_GENERATE_INTERNAL_LABEL
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
+ sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
+
+/*** Macros Controlling Initialization Routines. */
+
+#define INIT_SECTION_ASM_OP "\t.init"
+#define FINI_SECTION_ASM_OP "\t.fini"
+
+/*** Output of Assembler Instructions. */
+
+#define REGISTER_NAMES \
+ { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \
+ "%r8", "%r9", "%fp", "__arg__" }
+
+#define ADDITIONAL_REGISTER_NAMES \
+ { { "%a", 0 }, { "%ctx", 6 }, { "%r10" , 10 } }
+
+#define LOCAL_LABEL_PREFIX "."
+#define USER_LABEL_PREFIX ""
+
+#define PRINT_OPERAND(STREAM,X,CODE) \
+ bpf_print_operand ((STREAM),(X),(CODE))
+
+#define PRINT_OPERAND_ADDRESS(STREAM,X) \
+ bpf_print_operand_address ((STREAM), (X))
+
+/*** Assembler Commands for Alignment. */
+
+/* This is how to output an assembler line that says to advance the
+ location counter to a multiple of 2**LOG bytes. */
+#define ASM_OUTPUT_ALIGN(STREAM,LOG) \
+ fprintf (STREAM, "\t.align\t%d\n", (LOG))
+
+/* This is how to output an assembler line
+ that says to advance the location counter by SIZE bytes. */
+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
+ fprintf (FILE, "\t.skip\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n", (SIZE))
+
+/**** Miscellaneous Parameters. */
+
+/* Specify the machine mode that this machine uses for the index in
+ the tablejump instruction. */
+#define CASE_VECTOR_MODE DImode
+
+/* Define if operations between registers with integral mode smaller
+ than a word are always performed on the entire register. */
+#define WORD_REGISTER_OPERATIONS 1
+
+/* C expression indicating when insns that read memory in MEM_MODE, an
+ integral mode narrower than a word, set the bits outsize of
+ MEM_MODE to be either the sign-extension or the zero-extension of
+ the data read. */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* The maximum number of bytes that a single instruction can move
+ quickly between memory and registers or between two memory
+ locations. */
+#define MOVE_MAX 8
+
+/* An alias for the machine mode for pointers. */
+#define Pmode DImode
+
+/* An alias for the machine mode used for memory references to
+ functions being called, in 'call' RTL expressions. */
+#define FUNCTION_MODE Pmode
+
+/* No libm on eBPF (for now.) */
+#define MATH_LIBRARY ""
+
+/**** libgcc settings. */
+
+/* Iterating over the global constructors and destructors and
+ executing them requires the ability of doing indirect calls.
+
+ eBPF doesn't support indirect calls, so no chance of supporting
+ constructors and destructors. */
+#define DO_GLOBAL_CTORS_BODY \
+ do { } while (0)
+#define DO_GLOBAL_DTORS_BODY \
+ do { } while (0)
+
+#endif /* ! GCC_BPF_H */
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
new file mode 100644
index 00000000000..75383acef76
--- /dev/null
+++ b/gcc/config/bpf/bpf.md
@@ -0,0 +1,497 @@
+;; Machine description for eBPF.
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <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 "reg_or_memory_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 "reg_or_memory_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 "reg_or_memory_operand" "0,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 "mov_dst_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
index 00000000000..143107c2590
--- /dev/null
+++ b/gcc/config/bpf/bpf.opt
@@ -0,0 +1,123 @@
+; Options for the eBPF compiler port.
+
+; Copyright (C) 2019 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3. If not see
+; <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 InverseMask(LITTLE_ENDIAN)
+Generate big-endian eBPF.
+
+mlittle-endian
+Target RejectNegative Report Mask(LITTLE_ENDIAN)
+Generate little-endian eBPF.
+
+mframe-limit=
+Target Joined RejectNegative UInteger IntegerRange(0, 32767) Var(bpf_frame_limit) Init(512)
+Set a hard limit for the size of each stack frame, in bytes.
diff --git a/gcc/config/bpf/constraints.md b/gcc/config/bpf/constraints.md
new file mode 100644
index 00000000000..f27b785d9ce
--- /dev/null
+++ b/gcc/config/bpf/constraints.md
@@ -0,0 +1,32 @@
+;; Constraint definitions for eBPF.
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <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
index 00000000000..a3727acfc0a
--- /dev/null
+++ b/gcc/config/bpf/predicates.md
@@ -0,0 +1,72 @@
+;; 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 "reg_or_memory_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "memory_operand")))
+
+(define_predicate "mov_dst_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "memory_operand")))
+
+(define_predicate "mov_src_operand"
+ (ior (match_operand 0 "memory_operand")
+ (match_operand 0 "reg_or_imm_operand")
+ (match_operand 0 "lddw_operand")))
+
+(define_predicate "register_compare_operator"
+ (match_code "eq,ne,geu,gtu,ge,gt"))
+
diff --git a/gcc/config/bpf/t-bpf b/gcc/config/bpf/t-bpf
new file mode 100644
index 00000000000..e69de29bb2d
--
2.11.0
^ permalink raw reply [flat|nested] 18+ messages in thread