From patchwork Tue Oct 26 12:06:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guillermo E. Martinez" X-Patchwork-Id: 46658 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0CC0E385801C for ; Tue, 26 Oct 2021 12:07:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0CC0E385801C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1635250075; bh=bUOwcvP2dOTvBwGF0QunGs1QR60QDoS4ESKaWLc7rBE=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=OagecZNOxpw5BgwzP16vNXvRuPj9pByPT71dyNGJQ486RdyDNjQ1x77cp/CoHK6t9 hT48l20x4gBxitPGc4AUqo02R/qLzBuxKot0fDCCIu4Rf7d5VlLyKRsLecNLcDfawZ 8gc3pMqiTm8zRVNrIcVbsfMtowv/fpv6lXeTU1pU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by sourceware.org (Postfix) with ESMTPS id C11AB3858C27 for ; Tue, 26 Oct 2021 12:07:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C11AB3858C27 Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 19QAvQXQ026962 for ; Tue, 26 Oct 2021 12:07:19 GMT Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3bx4fhu2ma-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 26 Oct 2021 12:07:17 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 19QC1UGA105005 for ; Tue, 26 Oct 2021 12:07:10 GMT Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2169.outbound.protection.outlook.com [104.47.57.169]) by aserp3020.oracle.com with ESMTP id 3bx4gavg8e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 26 Oct 2021 12:07:10 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iKzqz7K1ktq0Allf9eQo5ExN/t6njI5skF6qB89/4Ur7W8eMiGy6Jy073EZEB3SgkRYiScN17zXpfqAPyR9bM9qZi8w6MgKpDQPfusUK3UDbjIg0Y+hFlN296tY72wVVRz4I0OdYtfFYxo/JkV0JpOD/9xRgTYYLancI81pXMk9t0ctnriJG6zFXtLBY46gssW0o5hMbEag5TsaulqxteuxBZwQ70WaB8BFOnvxAPDHxMBfbDgHwEn6m+bOAruy/Xu0UVNLLevyj0K+Vb3GN7iBn5n2VpeFdiYakWn0BfnpnYudB7y8QjDHx19V7FGbUycJaInd6QN4JzzgAJ/TqGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=bUOwcvP2dOTvBwGF0QunGs1QR60QDoS4ESKaWLc7rBE=; b=PwlyLN2wPj0+YR9NrTWnoI9IkGhQzyQAIAsjqse6g9paw7PmK0HjbmqKrBAW7FYkb9rWJXrIxdfi+HKfBx6WBDgJd0/Gcow2s7ky4m44qiHeyEm1y8D7JnB2IQsx9+smqu8e8pNp3qEDvuKR8i3RpzXc13MWRt4Q6XAqG519Ninj0ehlEsfgFpPj6eDmvnmMNRNEbac9HIanPRSVDLKHz0Hr7Oi0Bz6Ic/Dc1AX17sGzlpEzMKNeVRExyujyV+AKqAc0wug+CuRgrKDPlqnUn7/sUvh2zBaJin5DL+qnkVn/KSWUa9IC8ZdiPKRAoHucX+2uBbNfGvifJbf7gYt4bQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none Received: from BL0PR10MB2852.namprd10.prod.outlook.com (2603:10b6:208:76::22) by MN2PR10MB4016.namprd10.prod.outlook.com (2603:10b6:208:180::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4628.20; Tue, 26 Oct 2021 12:07:08 +0000 Received: from BL0PR10MB2852.namprd10.prod.outlook.com ([fe80::7126:e98e:9cff:8765]) by BL0PR10MB2852.namprd10.prod.outlook.com ([fe80::7126:e98e:9cff:8765%7]) with mapi id 15.20.4628.020; Tue, 26 Oct 2021 12:07:08 +0000 To: gcc-patches@gcc.gnu.org Subject: [PATCH v3] bpf: Add support to eBPF atomic instructions Date: Tue, 26 Oct 2021 07:06:56 -0500 Message-Id: <20211026120656.157544-1-guillermo.e.martinez@oracle.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: References: X-ClientProxiedBy: SN4PR0501CA0066.namprd05.prod.outlook.com (2603:10b6:803:41::43) To BL0PR10MB2852.namprd10.prod.outlook.com (2603:10b6:208:76::22) MIME-Version: 1.0 Received: from localhost.localdomain (187.248.82.110) by SN4PR0501CA0066.namprd05.prod.outlook.com (2603:10b6:803:41::43) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4649.13 via Frontend Transport; Tue, 26 Oct 2021 12:07:07 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 3ce4bd76-6ccc-4669-022d-08d998792204 X-MS-TrafficTypeDiagnostic: MN2PR10MB4016: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 9cfJMCQ3oTGAOpVvP7VVTx3SNpotTXp8dDmyvaP9PbECoPmM+jvFaHdBm2Hwd+LkqYFIqZnL/M1e/Uk25lnzFhDvpeP7i2RBRiZgQTkyzgMpqpW04Xr3nmkO+ZK+repgBjru1/mCJHCi9qhdcNr9ftikDvnkgpQq5TLG46LJFlIC89sIHHf7yrf8NamTlea0Pm4JmFjNmXSp9/cjBEw8+3/57igArUzZUQcjcu/6/6EJEja/bzNBXFHBHwFILnGE0q1P9dhW+WF5ZPyA/Qh9eTJBGE+C6R7tfXPTD6chhZe6YCrg35KjnspkbyfitPyIQvjs8kIprVhqjikmIGK6iiF9EKiUbF9aBPwVJCLh84tZW7JuZRU5tlvfUZuR1AYA4njnd7e7RfxUR5rr9Rz++O8HEtiJXVU6NwLmXpyK/WCHK7/qd4XRohcXLYNEQm/X1C2g6fK4hViQI5cENqnhXvBqXbJrVhNxNl58wVswiUiJmWRW4+S+7qPbCxkvv83rNJbxTwDkTJywkvTKbWPZNpwbFReh71RPMaRp//Qi+4zJPm2xuP40t9VrxvIOQh/I2/eFEe0/W2XRvNFI5oa9w28MqwCmrWKQW9CqgFH6spaWbJGNjIs2m2GW26ffD++vo4y2JzXeBMgtua/M+B1FXkKsxsSCEhB/fb4m5FvrD13s3vSpisOPGlpyXtz2cz3GvIhjGBvFgUf/W8ssussLkboMFED3saWxxOW3qNClGPjqTd2fnYgFwSJMVm+IIT0Lb4+J/Qe68dttqz9uzy73hOfMPkWfZTDV6k733AjnQNmAE6hgl6ji3Sw6rcNbVxN9q7qwsahzg4D67SZQwGIF0A== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BL0PR10MB2852.namprd10.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(508600001)(6506007)(6512007)(6916009)(966005)(316002)(52116002)(66556008)(1076003)(83380400001)(4326008)(66946007)(6666004)(26005)(30864003)(38100700002)(4001150100001)(86362001)(2906002)(38350700002)(6486002)(8936002)(103116003)(186003)(956004)(107886003)(66476007)(5660300002)(8676002)(2616005)(36756003)(2004002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Mvmc2gHETCH4Vt++/2jSoVrzTrCjHNkOisZKRIawh4Lo8Gn3y0M6AMCapPZxghYFim9EPdBPJTCg7EAht+99d08Sfo4nApl/0n54+gwfBpY4Xrja5gdQieJNP4BxDHpctya02Kjwf8BjyjX4FDQKB59v1OVPqKS1uyuH8ZEuOSoYU44+JWbAxeawHiA9Wv0N5EWhz23itGum1yZ1tZoCTfo7hcBLzLVJgbMSOcfsrlSfFs7Cr+esQl4r5hHE7QDvu0BUhcTKFy3+CnH08UJQbPBHRP7p1FkZ8bMTI0ygdr+aM8PXiEMEUAHEVD1KHsHK3Nsdg3maXgrX4OuClokppRgA0/1aq964UxHtHT6o9VmwfgPsEgElZrNNKd0L4ZiE2xaF1J7tQWXSKO9saSv5hsxTi1qPiWG035/GZ3dgeceLa+64cpsuQJ2Q6+qIfWz6yQBKjv1TgAMyusSgfwrVLwUBU5dI429r5KYHhhjzeJrbqvev67rnk1G1egLp5UbEVkYGalfRVLjF+qo0en9YZ64MHhvIsFpyriLPlqdF57V9J9qIT3Z6dbORuTsbcWv+HNFIuvN0K/H/5+VH4n5K3/h8mOPRyxVTIvhxPPPc14vRmacAgc3WzBQ10KHLm6cP96Ftau+80prlmzyAKeN1XFwkW7HpTWOgS8A3Lc7KxVYKpPbQ4DbCqwdA8zwtlxhVQ3IZ/PjiMhOlCFzbQhyMQurPC5gfk0qFxAXfryewDk6fVFieXwsV2xlkIesfRoO8yB+p5Awfx209bq6SltyMpzJMLIzy9+O3p7VXHXz+B9TedVAhC10SLGGR97hxVrGfOKg6JKdnO1gweyfpSw0Iz0/9T+yalWR1A1/HWGekSSyhnK0X8VsqMVN88J6eXcytHHOxC3KMns9KL8O8O6U6RA9Esn/KpVecAk0LvM4inI0zb5VWFxl1ttoax5GtbHX+NyBgWIxBogJW6Jq+OEhUn63HEFx9S/z9Dp2zO+jB4cz+Gb8x5jIEbphdC9GoHCjFxNbcWhLh+w2nwGCMpsitIwp8XQMoiZs3y6Y3sDF+p65Dct6faBDM1AyJCOpyJffQpJIhV2jDIedg1PTW20bCxqRdwYaDFQH4uO4AcqEtqubrg3mbimVMR7+22rLTEGUloE8wTxF9CF3L8MuYLOTHcB/5r5JP7bzhAkOM9AGXIASSjOjrzF5CZcwc04qC1h+CnIYCsnKAlyTuiE+y6hFVBfGFyjZsozuEq7H8pCCFrN5OcNB0x98y/thNVkkBbveMsecyBu95MguxXKvwLAkZP5Fn4t5wY92ctI+F9l8KPvbRTgAMIxatQ/heOgJiMIKw+OumDjBqW/KvHOpzsLQVhGTgAcVZSx6khSVX53Y9NbSq8MvE+pNykzpIUkQXGi6WQHzPT9qZH+yHkHcKB6fDu7+dgsJghFtYm3JvBr37pSlnNrmMo+6VcvQyhKocV9BAbtDjBv5BYh0VjUfqPEy3e6UuAiUXoHBE4Ntqwf5XHHeU+NgL91nYwR6Qf02LWEtPweohlIWQPNdtzJnSdaKx1qE6A9Hd6c9SRid8B5hRq2TJNgAlaVykBciGQsFApvZnrki2mSJwG1Zw3jJzPmi1L4hBJNDsn4F71CUrCHDWl0iaRfhuOQpfVOnUGPw/gv9hnJJNT7Xgvtd4xLCqQjDipQ== X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3ce4bd76-6ccc-4669-022d-08d998792204 X-MS-Exchange-CrossTenant-AuthSource: BL0PR10MB2852.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Oct 2021 12:07:08.0357 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Fl8gkX4pciE7hTSklNsu6sG6IoI02XjSuc/vUoUYzsbyPUqrBuCVdAqZ8Ujha0RNnGbatMCMTw2VaDBvKmax63AdHmWaYSvbrvuiuOb8cPA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR10MB4016 X-Proofpoint-Virus-Version: vendor=nai engine=6300 definitions=10148 signatures=668683 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 mlxlogscore=999 bulkscore=0 phishscore=0 mlxscore=0 spamscore=0 adultscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2110260069 X-Proofpoint-ORIG-GUID: GAcN6HQDTx8xKE5YBGuIOwLIp7jzPsKV X-Proofpoint-GUID: GAcN6HQDTx8xKE5YBGuIOwLIp7jzPsKV X-Spam-Status: No, score=-14.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, MSGID_FROM_MTA_HEADER, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "Guillermo E. Martinez via Gcc-patches" From: "Guillermo E. Martinez" Reply-To: "Guillermo E. Martinez" Cc: "Guillermo E. Martinez" Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hello people, This patch v3 to add support for atomics instructions in eBPF target, the rtl for eBPF atomics was splitted in a new file: atomic.md, Thanks Andrew for the comments, Kind Regards, Guillermo eBPF add support for atomic instructions, the following gcc built-in functions are implemented for bpf target using both: 32 and 64 bits data types: __atomic_fetch_add __atomic_fetch_sub __atomic_fetch_and __atomic_fetch_xor __atomic_fetch_or __atomic_exchange __atomic_compare_exchange_n Also calls to __atomic__fetch are fully supported. New define instructions were added to bpf.md along with its tests for gcc atomic built-in functions. In order to restrict/enable the use of `add + fetch' and the rest of atomic instructions the -m[no-]atomics was added. Those instructions are fully compliant with: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html https://www.kernel.org/doc/Documentation/networking/filter.rst This support depends of two previous submissions in CGEN and binutils-gdb projects: https://sourceware.org/pipermail/cgen/2021q3/002774.html https://sourceware.org/pipermail/binutils/2021-August/117798.html gcc/ * config/bpf/bpf.md: Add defines for atomic instructions. * config/bpf/bpf.c: Enable atomics by default in ISA v3. * config/bpf/bpf.h: Pass option to gas to disabled use of atomics (-mno-atomics). * config/bpf/bpf.opt: Add -m[no-]atomics option. * doc/invoke.texi: Add documentation for -m[no-a]tomics. gcc/testsuite/ * gcc.target/bpf/atomic-compare-exchange.c: New test. * gcc.target/bpf/atomic-exchange.c: Likewise. * gcc.target/bpf/atomic-add.c: Likewise. * gcc.target/bpf/atomic-and.c: Likewise. * gcc.target/bpf/atomic-or.c: Likewise. * gcc.target/bpf/atomic-sub.c: Likewise. * gcc.target/bpf/atomic-xor.c: Likewise. * gcc.target/bpf/atomics-disabled.c: Likewise. * gcc.target/bpf/ftest-mcpuv3-atomics.c: Likewise. * gcc.target/bpf/ftest-no-atomics-add.c: Likewise. --- gcc/ChangeLog | 8 + gcc/config/bpf/atomic.md | 160 ++++++++++++++++++ gcc/config/bpf/bpf.c | 2 + gcc/config/bpf/bpf.h | 12 +- gcc/config/bpf/bpf.md | 24 +-- gcc/config/bpf/bpf.opt | 4 + gcc/config/bpf/constraints.md | 3 + gcc/doc/invoke.texi | 12 +- gcc/testsuite/ChangeLog | 12 ++ .../gcc.target/bpf/atomic-add-fetch.c | 29 ++++ gcc/testsuite/gcc.target/bpf/atomic-and.c | 25 +++ .../gcc.target/bpf/atomic-compare-exchange.c | 28 +++ .../gcc.target/bpf/atomic-exchange.c | 19 +++ gcc/testsuite/gcc.target/bpf/atomic-or.c | 25 +++ gcc/testsuite/gcc.target/bpf/atomic-sub.c | 27 +++ gcc/testsuite/gcc.target/bpf/atomic-xor.c | 25 +++ .../gcc.target/bpf/atomics-disabled.c | 28 +++ .../gcc.target/bpf/ftest-mcpuv3-atomics.c | 36 ++++ .../gcc.target/bpf/ftest-no-atomics-add.c | 23 +++ 19 files changed, 482 insertions(+), 20 deletions(-) create mode 100644 gcc/config/bpf/atomic.md create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-add-fetch.c create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-and.c create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-compare-exchange.c create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-exchange.c create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-or.c create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-sub.c create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-xor.c create mode 100644 gcc/testsuite/gcc.target/bpf/atomics-disabled.c create mode 100644 gcc/testsuite/gcc.target/bpf/ftest-mcpuv3-atomics.c create mode 100644 gcc/testsuite/gcc.target/bpf/ftest-no-atomics-add.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 115f32e5061..782d33908ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2021-10-25 Guillermo E. Martinez + * config/bpf/bpf.md: Add defines for atomic instructions. + * config/bpf/bpf.c: Enable atomics by default in ISA v3. + * config/bpf/bpf.h: Pass option to gas to disable use of + atomics (-mno-atomics). + * config/bpf/bpf.opt: Add -m[no-]atomics option. + * doc/invoke.texi: Add documentation for -m[no-]atomics. + 2021-10-20 Alex Coplan * calls.c (initialize_argument_information): Remove some dead diff --git a/gcc/config/bpf/atomic.md b/gcc/config/bpf/atomic.md new file mode 100644 index 00000000000..9afc38f01ae --- /dev/null +++ b/gcc/config/bpf/atomic.md @@ -0,0 +1,160 @@ +;; Machine description for eBPF atomic Instructions. +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_mode_iterator AMO [SI DI]) + +(define_insn "atomic_add" + [(set (match_operand:AMO 0 "memory_operand" "+m") + (unspec_volatile:AMO + [(plus:AMO (match_dup 0) + (match_operand:AMO 1 "register_operand" "r")) + (match_operand:SI 2 "const_int_operand")] ;; Memory model. + UNSPEC_XADD))] + "" + "xadd\t%0,%1") + +(define_expand "atomic_fetch_add" + [(match_operand:AMO 0 "register_operand") + (match_operand:AMO 1 "memory_operand") + (match_operand:AMO 2 "nonmemory_operand") + (match_operand:AMO 3 "const_int_operand")] ;; Memory model + "" + { + if (bpf_has_atomics) + { + emit_insn + (gen_atomic_fetch_add_1 + (operands[0], operands[1], operands[2], operands[3])); + } + else + error ("invalid usage of the xadd return value"); + + DONE; + }) + + (define_insn "atomic_fetch_add_1" + [(set (match_operand:AMO 0 "register_operand" "=r") + (unspec_volatile:AMO + [(match_operand:AMO 1 "memory_operand" "+o") + (match_operand:AMO 2 "nonmemory_operand" "0") + (match_operand:AMO 3 "const_int_operand")] ;; Memory model + UNSPEC_XADD))] + "" + "xaddf\t%1,%0") + +(define_insn "atomic_fetch_and" + [(set (match_operand:AMO 0 "register_operand" "=r") + (unspec_volatile:AMO + [(match_operand:AMO 1 "memory_operand" "+o") + (match_operand:AMO 2 "nonmemory_operand" "0") + (match_operand:AMO 3 "const_int_operand")] + UNSPEC_XAND))] + "bpf_has_atomics" + "xand\t%1,%0") + +(define_insn "atomic_fetch_or" + [(set (match_operand:AMO 0 "register_operand" "=r") + (unspec_volatile:AMO + [(match_operand:AMO 1 "memory_operand" "+o") + (match_operand:AMO 2 "nonmemory_operand" "0") + (match_operand:AMO 3 "const_int_operand")] + UNSPEC_XOR))] + "bpf_has_atomics" + "xor\t%1,%0") + +(define_insn "atomic_fetch_xor" + [(set (match_operand:AMO 0 "register_operand" "=r") + (unspec_volatile:AMO + [(match_operand:AMO 1 "memory_operand" "+o") + (match_operand:AMO 2 "nonmemory_operand" "0") + (match_operand:AMO 3 "const_int_operand")] + UNSPEC_XXOR))] + "bpf_has_atomics" + "xxor\t%1,%0") + +(define_insn "atomic_exchange" + [(set (match_operand:AMO 0 "register_operand" "=r") + (unspec_volatile:AMO + [(match_operand:AMO 1 "memory_operand" "+o") + (match_operand:AMO 2 "nonmemory_operand" "0") + (match_operand:AMO 3 "const_int_operand")] + UNSPEC_XCHG))] + "bpf_has_atomics" + "xchg\t%1,%0") + +;; eBPF compare and exchange operation atomically compares the +;; value addressed by memory operand(%0) with _R0_(%1), so +;; there is a constraint to load the expected value in mentioned +;; register. If they match it is replaced with desired value(%3). +;; In either case, the value that was there before in %0 is +;; zero-extended and loaded back to R0. + +(define_expand "atomic_compare_and_swap" + [(match_operand:SI 0 "register_operand") ;; bool success + (match_operand:AMO 1 "register_operand") ;; old value + (match_operand:AMO 2 "memory_operand") ;; memory + (match_operand:AMO 3 "register_operand") ;; expected + (match_operand:AMO 4 "register_operand") ;; desired + (match_operand:SI 5 "const_int_operand") ;; is_weak (unused) + (match_operand:SI 6 "const_int_operand") ;; success model (unused) + (match_operand:SI 7 "const_int_operand")] ;; failure model (unused) + "" +{ + if (bpf_has_atomics) + { + emit_insn + (gen_atomic_compare_and_swap_1 + (operands[1], operands[2], operands[3], operands[4], operands[6])); + + /* Assume success operation, i.e memory operand + is matched with expected value. + */ + emit_move_insn (operands[0], const1_rtx); + rtx_code_label *success_label = gen_label_rtx (); + + /* At this point eBPF xcmp was executed, now we can ask + * for success exchange, and set suitable value for bool + * operand(%0) + */ + emit_cmp_and_jump_insns (operands[1], operands[3], EQ, 0, + GET_MODE (operands[1]), 1, success_label); + emit_move_insn (operands[0], const0_rtx); + + if (success_label) + { + emit_label (success_label); + LABEL_NUSES (success_label) = 1; + } + } + else + error ("unsupported atomic instruction"); + + DONE; +}) + +(define_insn "atomic_compare_and_swap_1" + [(set (match_operand:AMO 0 "register_operand" "=t") ;; must be r0 + (unspec_volatile:AMO + [(match_operand:AMO 1 "memory_operand" "+o") ;; memory + (match_operand:AMO 2 "register_operand" "0") ;; expected + (match_operand:AMO 3 "register_operand" "r") ;; desired + (match_operand:SI 4 "const_int_operand")] ;; success (unused) + UNSPEC_CMPXCHG))] + "bpf_has_atomics" + "xcmp\t%1,%3") diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index 82bb698bd91..5f489c829cc 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -253,6 +253,8 @@ bpf_option_override (void) if (bpf_has_jmp32 == -1) bpf_has_jmp32 = (bpf_isa >= ISA_V3); + if (bpf_has_atomics == -1) + bpf_has_atomics = (bpf_isa >= ISA_V3); } #undef TARGET_OPTION_OVERRIDE diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h index 82be0c3e190..d886e7e98ce 100644 --- a/gcc/config/bpf/bpf.h +++ b/gcc/config/bpf/bpf.h @@ -22,7 +22,9 @@ /**** Controlling the Compilation Driver. */ -#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf}" +#define ASM_SPEC \ + "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf} " \ + "%{mno-atomics:-mno-atomics} " #define LINK_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}" #define LIB_SPEC "" #define STARTFILE_SPEC "" @@ -176,6 +178,7 @@ enum reg_class { NO_REGS, /* no registers in set. */ + R0, /* register r0. */ ALL_REGS, /* all registers. */ LIM_REG_CLASSES /* max value + 1. */ }; @@ -189,6 +192,7 @@ enum reg_class #define REG_CLASS_NAMES \ { \ "NO_REGS", \ + "R0", \ "ALL_REGS" \ } @@ -202,14 +206,16 @@ enum reg_class #define REG_CLASS_CONTENTS \ { \ 0x00000000, /* NO_REGS */ \ - 0x00000fff, /* ALL_REGS */ \ + 0x00000001, /* R0 */ \ + 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 +#define REGNO_REG_CLASS(REGNO) \ + ((REGNO) == 0 ? R0 : 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 diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md index 436c8dfa059..97b1b02313d 100644 --- a/gcc/config/bpf/bpf.md +++ b/gcc/config/bpf/bpf.md @@ -25,6 +25,11 @@ (define_c_enum "unspec" [ UNSPEC_LDINDABS UNSPEC_XADD + UNSPEC_XAND + UNSPEC_XOR + UNSPEC_XXOR + UNSPEC_XCHG + UNSPEC_CMPXCHG ]) ;;;; Constants @@ -56,11 +61,10 @@ ;; 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" + "unknown,alu,alu32,end,ld,lddw,ldx,st,stx,jmp,multi" (const_string "unknown")) ;; Length of instruction in bytes. @@ -512,17 +516,5 @@ "ldabs\t%0" [(set_attr "type" "ld")]) -;;;; Atomic increments - -(define_mode_iterator AMO [SI DI]) - -(define_insn "atomic_add" - [(set (match_operand:AMO 0 "memory_operand" "+m") - (unspec_volatile:AMO - [(plus:AMO (match_dup 0) - (match_operand:AMO 1 "register_operand" "r")) - (match_operand:SI 2 "const_int_operand")] ;; Memory model. - UNSPEC_XADD))] - "" - "xadd\t%0,%1" - [(set_attr "type" "xadd")]) +;; include atomic instructions +(include "atomic.md") diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index e8b728ca69f..3eea3a75b62 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -146,6 +146,10 @@ mjmp32 Target Var(bpf_has_jmp32) Init(-1) Enable 32-bit jump instructions. +matomics +Target Var(bpf_has_atomics) Init(-1) +Enable eBPF atomic instructions. + mcpu= Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V3) diff --git a/gcc/config/bpf/constraints.md b/gcc/config/bpf/constraints.md index 66b7764d775..9606b6e150e 100644 --- a/gcc/config/bpf/constraints.md +++ b/gcc/config/bpf/constraints.md @@ -29,3 +29,6 @@ (define_constraint "S" "A constant call address." (match_code "const,symbol_ref,label_ref,const_int")) + +(define_register_constraint "t" "R0" + "Register r0") diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6d1e328571a..136a1e87fec 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -905,7 +905,7 @@ Objective-C and Objective-C++ Dialects}. @emph{eBPF Options} @gccoptlist{-mbig-endian -mlittle-endian -mkernel=@var{version} --mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re +-mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re -matomics -mjmpext -mjmp32 -malu32 -mcpu=@var{version}} @emph{FR30 Options} @@ -22824,6 +22824,7 @@ All features of v2, plus: @itemize @minus @item 32-bit jump operations, as in @option{-mjmp32} @item 32-bit ALU operations, as in @option{-malu32} +@item Atomics instructions @end itemize @end table @@ -22846,6 +22847,15 @@ the restrictions imposed by the BPF architecture: @item Save and restore callee-saved registers at function entry and exit, respectively. @end itemize + +@item -matomics +Enable use of eBPF atomic instructions. This is set by default when +eBPF ISA is greater or equal to @samp{v3}. If this option is set, +then GCC for eBPF can emit a full set of atomic instructions, those +atomics may not be executed by all kernel versions. This option is not +enabled by default when eBPF ISA is lower than @samp{v3}, so atomics are +disabled with the exception of @samp{add} instruction, allowing +backward compatibility in older kernel versions. @end table @node FR30 Options diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 602b727f1a5..10ac40d88be 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2021-10-25 Guillermo E. Martinez + * gcc.target/bpf/atomic-compare-exchange.c: New test. + * gcc.target/bpf/atomic-exchange.c: Likewise. + * gcc.target/bpf/atomic-add.c: Likewise. + * gcc.target/bpf/atomic-and.c: Likewise. + * gcc.target/bpf/atomic-or.c: Likewise. + * gcc.target/bpf/atomic-sub.c: Likewise. + * gcc.target/bpf/atomic-xor.c: Likewise. + * gcc.target/bpf/atomics-disabled.c: Likewise. + * gcc.target/bpf/ftest-mcpuv3-atomics.c: Likewise. + * gcc.target/bpf/ftest-no-atomics-add.c: Likewise. + 2021-10-20 Tamar Christina * gcc.target/aarch64/mvn-cmeq0-1.c: New test. diff --git a/gcc/testsuite/gcc.target/bpf/atomic-add-fetch.c b/gcc/testsuite/gcc.target/bpf/atomic-add-fetch.c new file mode 100644 index 00000000000..047a0688b00 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/atomic-add-fetch.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ + +long delta; +long *val; + +/* + * fetch atomic add is only available with -matomics or + * -mcpu=v3 option. + */ +void +foo () +{ + volatile long k; + + k = __atomic_fetch_add (val, delta, __ATOMIC_RELAXED); + k = __atomic_fetch_add ((int*)val, delta, __ATOMIC_RELAXED); + + k = __atomic_add_fetch (val, delta, __ATOMIC_RELAXED); + k = __atomic_add_fetch ((int*)val, delta, __ATOMIC_RELAXED); + + k = __sync_fetch_and_add (val, delta, __ATOMIC_RELAXED); + k = __sync_fetch_and_add ((int*)val, delta, __ATOMIC_RELAXED); + + k = __sync_add_and_fetch (val, delta, __ATOMIC_RELAXED); + k = __sync_add_and_fetch ((int*)val, delta, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler "xaddfdw\t.*" } } */ +/* { dg-final { scan-assembler "xaddfw\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/atomic-and.c b/gcc/testsuite/gcc.target/bpf/atomic-and.c new file mode 100644 index 00000000000..6cc05a824f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/atomic-and.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ + +long mask; +long *val; + +void +foo () +{ + long k; + + k = __atomic_fetch_and (val, mask, __ATOMIC_RELAXED); + k = __atomic_fetch_and ((int*)val, mask, __ATOMIC_RELAXED); + + k = __atomic_and_fetch (val, mask, __ATOMIC_RELAXED); + k = __atomic_and_fetch ((int*)val, mask, __ATOMIC_RELAXED); + + k = __sync_fetch_and_and (val, mask, __ATOMIC_RELAXED); + k = __sync_fetch_and_and ((int*)val, mask, __ATOMIC_RELAXED); + + k = __sync_and_and_fetch (val, mask, __ATOMIC_RELAXED); + k = __sync_and_and_fetch ((int*)val, mask, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler "xanddw\t.*" } } */ +/* { dg-final { scan-assembler "xandw\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/atomic-compare-exchange.c b/gcc/testsuite/gcc.target/bpf/atomic-compare-exchange.c new file mode 100644 index 00000000000..d522697ec9e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/atomic-compare-exchange.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ + +long val; +long ptr; +long expected; +long desired; + +void +foo () +{ + int done; + + done = __atomic_compare_exchange_n (&ptr, &expected, desired, + 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + done = __atomic_compare_exchange_n ((int *)&ptr, (int *)&expected, + (int)desired, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + + done = __atomic_compare_exchange (&ptr, &expected, &desired, + 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + done = __atomic_compare_exchange ((int *)&ptr, (int *)&expected, + (int *)&desired, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + + done = __sync_bool_compare_and_swap (&ptr, expected, desired); + done = __sync_bool_compare_and_swap ((int*)&ptr, expected, desired); +} + +/* { dg-final { scan-assembler "xcmpdw\t.*" } } */ +/* { dg-final { scan-assembler "xcmpw\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/atomic-exchange.c b/gcc/testsuite/gcc.target/bpf/atomic-exchange.c new file mode 100644 index 00000000000..f4e60568f7f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/atomic-exchange.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +long val; +long ptr; + +void +foo () +{ + long prev; + + __atomic_exchange(&ptr, &val, &prev, __ATOMIC_RELAXED); + prev = __atomic_exchange_n(&ptr, val, __ATOMIC_RELAXED); + + __atomic_exchange((int *)&ptr, (int *)&val, (int *)&prev, __ATOMIC_RELAXED); + prev = __atomic_exchange_n((int *)&ptr, (int)val, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler "xchgdw\t.*" } } */ +/* { dg-final { scan-assembler "xchgw\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/atomic-or.c b/gcc/testsuite/gcc.target/bpf/atomic-or.c new file mode 100644 index 00000000000..af9a999e02a --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/atomic-or.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ + +long bits; +long *val; + +void +foo () +{ + long k; + + k = __atomic_fetch_or (val, bits, __ATOMIC_RELAXED); + k = __atomic_fetch_or ((int *)val, bits, __ATOMIC_RELAXED); + + k = __atomic_or_fetch (val, bits, __ATOMIC_RELAXED); + k = __atomic_or_fetch ((int*)val, bits, __ATOMIC_RELAXED); + + k = __sync_fetch_and_or (val, bits, __ATOMIC_RELAXED); + k = __sync_fetch_and_or ((int*)val, bits, __ATOMIC_RELAXED); + + k = __sync_or_and_fetch (val, bits, __ATOMIC_RELAXED); + k = __sync_or_and_fetch ((int*)val, bits, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler "xordw\t.*" } } */ +/* { dg-final { scan-assembler "xorw\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/atomic-sub.c b/gcc/testsuite/gcc.target/bpf/atomic-sub.c new file mode 100644 index 00000000000..92b95f6f368 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/atomic-sub.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ + +long delta; +long *val; + +void +foo () +{ + volatile long k; + + k = __atomic_fetch_sub (val, delta, __ATOMIC_RELAXED); + k = __atomic_fetch_sub ((int*)val, delta, __ATOMIC_RELAXED); + + k = __atomic_sub_fetch (val, delta, __ATOMIC_RELAXED); + k = __atomic_sub_fetch ((int*)val, delta, __ATOMIC_RELAXED); + + __sync_fetch_and_sub (val, delta, __ATOMIC_RELAXED); + __sync_fetch_and_sub ((int*)val, delta, __ATOMIC_RELAXED); + + k = __sync_sub_and_fetch (val, delta, __ATOMIC_RELAXED); + k = __sync_sub_and_fetch ((int*)val, delta, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler "xadddw\t.*" } } */ +/* { dg-final { scan-assembler "xaddw\t.*" } } */ +/* { dg-final { scan-assembler "xaddfdw\t.*" } } */ +/* { dg-final { scan-assembler "xaddfw\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/atomic-xor.c b/gcc/testsuite/gcc.target/bpf/atomic-xor.c new file mode 100644 index 00000000000..433600395a6 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/atomic-xor.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ + +long bits; +long *val; + +void +foo () +{ + long k; + + k = __atomic_fetch_xor (val, bits, __ATOMIC_RELAXED); + k = __atomic_fetch_xor ((int *)val, bits, __ATOMIC_RELAXED); + + k = __atomic_xor_fetch (val, bits, __ATOMIC_RELAXED); + k = __atomic_xor_fetch ((int*)val, bits, __ATOMIC_RELAXED); + + k = __sync_fetch_and_xor (val, bits, __ATOMIC_RELAXED); + k = __sync_fetch_and_xor ((int*)val, bits, __ATOMIC_RELAXED); + + k = __sync_xor_and_fetch (val, bits, __ATOMIC_RELAXED); + k = __sync_xor_and_fetch ((int*)val, bits, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler "xxordw\t.*" } } */ +/* { dg-final { scan-assembler "xxorw\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/atomics-disabled.c b/gcc/testsuite/gcc.target/bpf/atomics-disabled.c new file mode 100644 index 00000000000..b2bf040a35c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/atomics-disabled.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=v2" } */ +/* { dg-xfail-if "" { bpf-*-* } } */ + +long delta; +long bits; +long *val; +long ptr; + +/* Atomic instructions are disabled when eBPF ISA version + * is lower than v3 or -mno-atomics is set. + */ + +void +foo () +{ + volatile long k; + + __atomic_fetch_add (val, delta, __ATOMIC_RELAXED); + k = __atomic_fetch_add (val, delta, __ATOMIC_RELAXED); + k = __atomic_fetch_and ((int*)val, delta, __ATOMIC_RELAXED); + + __atomic_compare_exchange_n (&ptr, &delta, bits, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + __atomic_exchange(&ptr, &val, &delta, __ATOMIC_RELAXED); + + k = __atomic_fetch_or (val, bits, __ATOMIC_RELAXED); + k = __atomic_fetch_xor (val, bits, __ATOMIC_RELAXED); +} diff --git a/gcc/testsuite/gcc.target/bpf/ftest-mcpuv3-atomics.c b/gcc/testsuite/gcc.target/bpf/ftest-mcpuv3-atomics.c new file mode 100644 index 00000000000..4258c8fa300 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/ftest-mcpuv3-atomics.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=v3" } */ + +long delta; +long bits; +long *val; +long ptr; + +/* Atomic instructions are enabled by default in eBPF ISA v3, + * but those instructions can be removed from ISA v3 adding + * -mno-atomics option. + */ + +void +foo () +{ + volatile long k; + + __atomic_fetch_add (val, delta, __ATOMIC_RELAXED); + k = __atomic_fetch_add (val, delta, __ATOMIC_RELAXED); + k = __atomic_fetch_and ((int*)val, delta, __ATOMIC_RELAXED); + + __atomic_compare_exchange_n (&ptr, &delta, bits, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + __atomic_exchange(&ptr, &val, &delta, __ATOMIC_RELAXED); + + k = __atomic_fetch_or (val, bits, __ATOMIC_RELAXED); + k = __atomic_fetch_xor (val, bits, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler "xadddw\t.*" } } */ +/* { dg-final { scan-assembler "xaddfdw\t.*" } } */ +/* { dg-final { scan-assembler "xandw\t.*" } } */ +/* { dg-final { scan-assembler "xcmpdw\t.*" } } */ +/* { dg-final { scan-assembler "xchgdw\t.*" } } */ +/* { dg-final { scan-assembler "xordw\t.*" } } */ +/* { dg-final { scan-assembler "xxordw\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/ftest-no-atomics-add.c b/gcc/testsuite/gcc.target/bpf/ftest-no-atomics-add.c new file mode 100644 index 00000000000..6cef3bc3bc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/ftest-no-atomics-add.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-mno-atomics" } */ +/* { dg-xfail-if "" { bpf-*-* } } */ + +long delta; +long *val; + +/* Assignment of the return value for xadd instruction + * is not allowed when atomic instructions are disabled: + * -mno-atomics or mcpu=v{1|2}. + */ + +void +foo () +{ + volatile long k; + + k = __atomic_fetch_add (val, delta, __ATOMIC_RELAXED); + k = __atomic_fetch_add ((int*)val, delta, __ATOMIC_RELAXED); + + k = __atomic_add_fetch (val, delta, __ATOMIC_RELAXED); + k = __atomic_add_fetch ((int*)val, delta, __ATOMIC_RELAXED); +}