From patchwork Wed Aug 2 12:09:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Ball X-Patchwork-Id: 129796 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9f41:0:b0:3e4:2afc:c1 with SMTP id v1csp408386vqx; Wed, 2 Aug 2023 05:11:36 -0700 (PDT) X-Google-Smtp-Source: APBJJlHVgsbz9e+GQ5qEZCwK36OM+n9JYHxfWBKBrBRxwLgFaVcqPWyMVmIk43BKwdJvNSvlS9pl X-Received: by 2002:a17:906:30d7:b0:994:55ce:1630 with SMTP id b23-20020a17090630d700b0099455ce1630mr4337754ejb.42.1690978296020; Wed, 02 Aug 2023 05:11:36 -0700 (PDT) Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id qk29-20020a170906d9dd00b0098e422d6759si10772263ejb.554.2023.08.02.05.11.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Aug 2023 05:11:36 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=XycIdrqP; arc=fail (signature failed); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3588238582BE for ; Wed, 2 Aug 2023 12:11:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3588238582BE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1690978294; bh=zaBoF9EmWaGD05ixae5OKLWbNHhqeGftbVjnTZ3fGY0=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=XycIdrqPaQHHSVP5CiUYf7cJ2QZzvU7Vk9RP7dQFjg7N120Nr8haBjZar1TDoah4d dnT0IkF8yqTL2CReJ94Mw+Jz3v7xq4hVZpzfFxN0AVGg4jRTKtS8QkyxJobWD+X+h2 51CBQeFEPxC/KoxQMQ4nRQRzjFnN0ku5geSKH/fE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from EUR02-DB5-obe.outbound.protection.outlook.com (mail-db5eur02on2079.outbound.protection.outlook.com [40.107.249.79]) by sourceware.org (Postfix) with ESMTPS id 7F8433858D1E for ; Wed, 2 Aug 2023 12:10:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7F8433858D1E Received: from DB8PR03CA0024.eurprd03.prod.outlook.com (2603:10a6:10:be::37) by DU0PR08MB9077.eurprd08.prod.outlook.com (2603:10a6:10:471::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.45; Wed, 2 Aug 2023 12:10:35 +0000 Received: from DBAEUR03FT045.eop-EUR03.prod.protection.outlook.com (2603:10a6:10:be:cafe::3d) by DB8PR03CA0024.outlook.office365.com (2603:10a6:10:be::37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.45 via Frontend Transport; Wed, 2 Aug 2023 12:10:35 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by DBAEUR03FT045.mail.protection.outlook.com (100.127.142.142) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.45 via Frontend Transport; Wed, 2 Aug 2023 12:10:35 +0000 Received: ("Tessian outbound ba2f3d95109c:v145"); Wed, 02 Aug 2023 12:10:35 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: fd7fbe8081858f10 X-CR-MTA-TID: 64aa7808 Received: from 13dc5dfca5b3.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 49659FCE-9943-4177-B148-67434A9BC717.1; Wed, 02 Aug 2023 12:10:28 +0000 Received: from EUR03-AM7-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 13dc5dfca5b3.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Wed, 02 Aug 2023 12:10:28 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=F2teyJGt/bUvSxxRtiBKYHGDVzR+2NHuaALtSVrA3Vk3zHj7VZpQ0elOLDVnqwwkBH7EfJlxHxX2itRMAvZASQbjDNkFcq5jWnJ/TD2XMZGTY2PBy8kb17ax4YUgmJqOTvRlHXHGloclve8aSy2V8aDNza1ucbM7lAKoc4vGXu4CVvWd4NDCFn1NYi7c7xLJjvKrczwDSuo1aa+069HGlyRLA2MrDntUNG7Z0e2Aru5KGbGrF/4feDZGwmmjIjxJcd366LDnqIx+S5L3VWtfdpiNKuuxN58w9CSEEmFyDeETOv9HS+tVjOSCqMrFPDYqdIp7MjrPiAWsYvDBV7mhHg== 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=zaBoF9EmWaGD05ixae5OKLWbNHhqeGftbVjnTZ3fGY0=; b=HnqGgahYllVZaQ9I3CgR8PvJc8S/TCcrxlnhKRVoekPbwuWZUqT0ia7J0Gp+/KkPlzVdnsFszq/kt4PfKxLkJOuVd0J+ywJxrEs0iYamhsE1qzg0X7F3PJ5jrNINDQ2yYernzLJ6IGMVEC/o3CJGG2DBTrwYMtLDBl0r+BKgCsS/LK3tGe6ur+otnbLG/gbwdayA1mK7NwGqAn6afzLWOh2Ofb4xPsFnZM3GWjKeTvjJ8bVWFwUF4ac8EB/QSzuEUGEREBYLhidHW//dPBlKmUuBLWI65sbIB9vgLcfzrsCdovCmK1KJtfgbDcf3q2+HBm2wkVDdwOw7z3Gbl2ho+w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from DB9PR08MB6957.eurprd08.prod.outlook.com (2603:10a6:10:2bc::10) by GV1PR08MB8107.eurprd08.prod.outlook.com (2603:10a6:150:94::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.45; Wed, 2 Aug 2023 12:10:25 +0000 Received: from DB9PR08MB6957.eurprd08.prod.outlook.com ([fe80::466d:46ab:e188:aead]) by DB9PR08MB6957.eurprd08.prod.outlook.com ([fe80::466d:46ab:e188:aead%3]) with mapi id 15.20.6631.045; Wed, 2 Aug 2023 12:10:25 +0000 Message-ID: Date: Wed, 2 Aug 2023 13:09:54 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 Subject: [PATCH] aarch64: SVE/NEON Bridging intrinsics To: "gcc-patches@gcc.gnu.org" , Richard Sandiford , Richard Earnshaw , Kyrylo Tkachov , Marcus Shawcroft Content-Language: en-US X-ClientProxiedBy: LO2P123CA0090.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:138::23) To DB9PR08MB6957.eurprd08.prod.outlook.com (2603:10a6:10:2bc::10) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: DB9PR08MB6957:EE_|GV1PR08MB8107:EE_|DBAEUR03FT045:EE_|DU0PR08MB9077:EE_ X-MS-Office365-Filtering-Correlation-Id: a902d5cf-b965-412a-6502-08db93517a67 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: XIl9Bxv2f9My8fBepQ2dp0wAJEqDIyCfEjoEsTcIh39VN7vRnUisRi5pvTWbNIY+S79we3Cu0R7rwQK5ymbM+j33WJjbK2JPNx5nmYjTlRFQjApR264jCFmSwidYFdWN19XZGrCFerz0Z6MhjzkRK2fRSJlQ4gFCgO7GxQDVokSyJST3/REkDH2+zMQq0dtCeLp/Z9qWyibt3NK0zEpLY6K/INqwLkbwLMQsnLJgAClkXoId1oRUhXJszWSTvUHGKFZO+HntgyQiryDNqwZrEcIQgq6fpqbDWIRmqVJwUgMwjyhDUKk1Bvb2y0bp0EIMWq6TId6ooFUINOnHrgSMga6IOoNzX6Uq6e5X73tph11fy8hVjCXz6XmRND8bPJtlLCKrs7OIG4l/3WuGsJdQP4FTK43oJTQGqudctjpzUzQCXYVUbMNs5AHhn/6u5bbJpPN74ppMEU9vib+5StqFV65+TLH11Lfjf2pqmr6qtMWW+QFNOZOlB5VzpHN2hv4Bs5R+UmOaLfWQAsTvGaLcVnQClxZqLDqEJWIu2N3ku4o4w9m0qkaa0xTIGUANEfUxqhE09jYsRaEhZaQ73S6lSI3YzEllxTmQTMplJH/ErOM/rj1MYk6tn8GmT8MXQE0ZOt0vHsRdva/Qo9T0SqQRHEiZQflufE3oHlOPV3uN8UG6//bBNT6VQ5QfU/vAFSrS X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DB9PR08MB6957.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230028)(4636009)(376002)(366004)(396003)(346002)(136003)(39860400002)(451199021)(31686004)(31696002)(86362001)(36756003)(478600001)(110136005)(38100700002)(2616005)(186003)(83380400001)(6506007)(26005)(41300700001)(8676002)(8936002)(44832011)(6512007)(6666004)(6486002)(316002)(30864003)(66476007)(6636002)(5660300002)(66946007)(2906002)(66556008)(2004002)(45980500001)(43740500002)(357404004); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR08MB8107 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DBAEUR03FT045.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 1f5f13c3-608e-4a3f-a249-08db9351741b X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 5Vjx8/Ld3ui3EoEvZ9C8fDx6sYzi3/MTjmMqp9ugYyISJt7CL4ukYtG6Ig2BEC0HcKTOB7Qr5iTn+8yZEjttyE4FDemDqgD/YX3iTaf6n5wggDN+tCgKlhIs4wn77UXfErHO13JmGE+KGpxbocFa3DduUVKQBKKQclIiMBMFnlCTWiTMw9CjmbAVHp5WIC/He5Ce2buJto1fqrJ/LWqDAP6HBZyFqJt5nhnHjQVCA8QpUoB1QQPI6CaIQGvb4iF13Y9BrEs+Gof3CiwszSIUj9YzbYlC/U/JuEGdh4qzl5ExqZ6Y0O9B5ul7vXZ2USWxQYiuQ1+OzFW8keZDIjG0Piz9h0RJC+ig71QS9/mAfYPv16AFdHWb/FnSGASM2JqSbATZWOmK5m7YLEJz1nF4jQq4k1/OsraXIpEE4Eq90O1y9iYa3wLqRtbriwUg05Yc3767BD5xXiu4nwi0iIePCgKwlBgqAobfQ/shRsh1cnufi/lG2NnktJPn3X8+F4G+6AJA94QKNIUISfbNpV1b12gs6HjbD3dSBiQwlRUPjiOdgWxOlwMpC8tv8KIbt1fU1SC6Hnr9a1T3YdTeiPvTcsHfTokQKXBdxuP1A98V2hj7Q2LNyz7j+cqCWrhvQkbqy+gN2EyJabTvJ32pvv+3SL9AfZBu5NOnyEFyq5a4m83UzX4lx3qaUDsZUutv2ur/xvDfAuGxJrnErIne/rFdrRcTMMMsybe/m91JqKkjOedXdCI85UWV9XM1q+ZDDpDfWneC4BsPAJZRSd/CFaXI8BJ2PCwdJkcwmEME9v/uIjQpXdDgDgBU5KRzw3Q6OVva X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230028)(4636009)(346002)(39860400002)(136003)(396003)(376002)(451199021)(82310400008)(36840700001)(40470700004)(46966006)(8676002)(5660300002)(36860700001)(47076005)(82740400003)(83380400001)(2616005)(356005)(81166007)(41300700001)(30864003)(316002)(336012)(186003)(8936002)(6506007)(26005)(31686004)(6636002)(86362001)(31696002)(70206006)(70586007)(6512007)(2906002)(6486002)(6666004)(40460700003)(36756003)(478600001)(110136005)(44832011)(40480700001)(2004002)(43740500002)(357404004); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Aug 2023 12:10:35.8131 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a902d5cf-b965-412a-6502-08db93517a67 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: DBAEUR03FT045.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9077 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_NONE, KAM_LOTSOFHASH, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Richard Ball via Gcc-patches From: Richard Ball Reply-To: Richard Ball Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773119257633043301 X-GMAIL-MSGID: 1773119257633043301 ACLE has added intrinsics to bridge between SVE and Neon. The NEON_SVE Bridge adds intrinsics that allow conversions between NEON and SVE vectors. This patch adds support to GCC for the following 3 intrinsics: svset_neonq, svget_neonq and svdup_neonq gcc/ChangeLog: * config.gcc: Adds new header to config. * config/aarch64/aarch64-builtins.cc (GTY): Externs aarch64_simd_types. * config/aarch64/aarch64-c.cc (aarch64_pragma_aarch64): Defines pragma for arm_neon_sve_bridge.h. * config/aarch64/aarch64-protos.h: New function. * config/aarch64/aarch64-sve-builtins-base.h: New intrinsics. * config/aarch64/aarch64-sve-builtins-base.cc (class svget_neonq_impl): New intrinsic implementation. (class svset_neonq_impl): Likewise. (class svdup_neonq_impl): Likewise. (NEON_SVE_BRIDGE_FUNCTION): New intrinsics. * config/aarch64/aarch64-sve-builtins-functions.h (NEON_SVE_BRIDGE_FUNCTION): Defines macro for NEON_SVE_BRIDGE functions. * config/aarch64/aarch64-sve-builtins-shapes.h: New shapes. * config/aarch64/aarch64-sve-builtins-shapes.cc (parse_neon_type): Parser for NEON types. (parse_element_type): Add NEON element types. (parse_type): Likewise. (NEON_SVE_BRIDGE_SHAPE): Defines macro for NEON_SVE_BRIDGE shapes. (struct get_neonq_def): Defines function shape for get_neonq. (struct set_neonq_def): Defines function shape for set_neonq. (struct dup_neonq_def): Defines function shape for dup_neonq. * config/aarch64/aarch64-sve-builtins.cc (DEF_NEON_SVE_FUNCTION): Defines macro for NEON_SVE_BRIDGE functions. (handle_arm_neon_sve_bridge_h): Handles #pragma arm_neon_sve_bridge.h. * config/aarch64/aarch64-builtins.h: New header file to extern neon types. * config/aarch64/aarch64-neon-sve-bridge-builtins.def: New instrinsics function def file. * config/aarch64/arm_neon_sve_bridge.h: New header file. gcc/testsuite/ChangeLog: * gcc.c-torture/execute/neon-sve-bridge.c: New test. ############################################################################# diff --git a/gcc/config.gcc b/gcc/config.gcc index d88071773c9e1280cc5f38e36e09573214323b48..ca55992200dbe58782c3dbf66906339de021ba6b 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -334,7 +334,7 @@ m32c*-*-*) ;; aarch64*-*-*) cpu_type=aarch64 - extra_headers="arm_fp16.h arm_neon.h arm_bf16.h arm_acle.h arm_sve.h" + extra_headers="arm_fp16.h arm_neon.h arm_bf16.h arm_acle.h arm_sve.h arm_neon_sve_bridge.h" c_target_objs="aarch64-c.o" cxx_target_objs="aarch64-c.o" d_target_objs="aarch64-d.o" diff --git a/gcc/config/aarch64/aarch64-builtins.h b/gcc/config/aarch64/aarch64-builtins.h new file mode 100644 index 0000000000000000000000000000000000000000..eebde448f92c230c8f88b4da1ca8ebd9670b1536 --- /dev/null +++ b/gcc/config/aarch64/aarch64-builtins.h @@ -0,0 +1,86 @@ +/* Builtins' description for AArch64 SIMD architecture. + Copyright (C) 2023 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 + . */ +#ifndef GCC_AARCH64_BUILTINS_H +#define GCC_AARCH64_BUILTINS_H +#include "tree.h" +enum aarch64_type_qualifiers +{ + /* T foo. */ + qualifier_none = 0x0, + /* unsigned T foo. */ + qualifier_unsigned = 0x1, /* 1 << 0 */ + /* const T foo. */ + qualifier_const = 0x2, /* 1 << 1 */ + /* T *foo. */ + qualifier_pointer = 0x4, /* 1 << 2 */ + /* Used when expanding arguments if an operand could + be an immediate. */ + qualifier_immediate = 0x8, /* 1 << 3 */ + qualifier_maybe_immediate = 0x10, /* 1 << 4 */ + /* void foo (...). */ + qualifier_void = 0x20, /* 1 << 5 */ + /* 1 << 6 is now unused */ + /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum + rather than using the type of the operand. */ + qualifier_map_mode = 0x80, /* 1 << 7 */ + /* qualifier_pointer | qualifier_map_mode */ + qualifier_pointer_map_mode = 0x84, + /* qualifier_const | qualifier_pointer | qualifier_map_mode */ + qualifier_const_pointer_map_mode = 0x86, + /* Polynomial types. */ + qualifier_poly = 0x100, + /* Lane indices - must be in range, and flipped for bigendian. */ + qualifier_lane_index = 0x200, + /* Lane indices for single lane structure loads and stores. */ + qualifier_struct_load_store_lane_index = 0x400, + /* Lane indices selected in pairs. - must be in range, and flipped for + bigendian. */ + qualifier_lane_pair_index = 0x800, + /* Lane indices selected in quadtuplets. - must be in range, and flipped for + bigendian. */ + qualifier_lane_quadtup_index = 0x1000, +}; +#define ENTRY(E, M, Q, G) E, +enum aarch64_simd_type +{ +#include "aarch64-simd-builtin-types.def" + ARM_NEON_H_TYPES_LAST +}; +#undef ENTRY +struct GTY(()) aarch64_simd_type_info +{ + enum aarch64_simd_type type; + /* Internal type name. */ + const char *name; + /* Internal type name(mangled). The mangled names conform to the + AAPCS64 (see "Procedure Call Standard for the ARM 64-bit Architecture", + Appendix A). To qualify for emission with the mangled names defined in + that document, a vector type must not only be of the correct mode but also + be of the correct internal AdvSIMD vector type (e.g. __Int8x8_t); these + types are registered by aarch64_init_simd_builtin_types (). In other + words, vector types defined in other ways e.g. via vector_size attribute + will get default mangled names. */ + const char *mangle; + /* Internal type. */ + tree itype; + /* Element type. */ + tree eltype; + /* Machine mode the internal type maps to. */ + enum machine_mode mode; + /* Qualifiers. */ + enum aarch64_type_qualifiers q; +}; +extern aarch64_simd_type_info aarch64_simd_types[]; +#endif \ No newline at end of file diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 04f59fd9a54306d6422b03e32dce79bc00aed4f8..6a3aca6420624ad5ea93d64d7ed580791d65d4e4 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -923,7 +923,7 @@ struct GTY(()) aarch64_simd_type_info #define ENTRY(E, M, Q, G) \ {E, "__" #E, #G "__" #E, NULL_TREE, NULL_TREE, E_##M##mode, qualifier_##Q}, -static GTY(()) struct aarch64_simd_type_info aarch64_simd_types [] = { +extern GTY(()) struct aarch64_simd_type_info aarch64_simd_types [] = { #include "aarch64-simd-builtin-types.def" }; #undef ENTRY diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc index 578ec6f45b06347d90f951b37064006786baf10f..ada8b81a7bef6c2e58b07324a7bfc38eecb651da 100644 --- a/gcc/config/aarch64/aarch64-c.cc +++ b/gcc/config/aarch64/aarch64-c.cc @@ -294,6 +294,8 @@ aarch64_pragma_aarch64 (cpp_reader *) handle_arm_neon_h (); else if (strcmp (name, "arm_acle.h") == 0) handle_arm_acle_h (); + else if (strcmp (name, "arm_neon_sve_bridge.h") == 0) + aarch64_sve::handle_arm_neon_sve_bridge_h (); else error ("unknown %<#pragma GCC aarch64%> option %qs", name); } diff --git a/gcc/config/aarch64/aarch64-neon-sve-bridge-builtins.def b/gcc/config/aarch64/aarch64-neon-sve-bridge-builtins.def new file mode 100644 index 0000000000000000000000000000000000000000..0c3cf233c9382b2f7420379054a53fa846d46c8c --- /dev/null +++ b/gcc/config/aarch64/aarch64-neon-sve-bridge-builtins.def @@ -0,0 +1,28 @@ +/* Builtin lists for AArch64 NEON-SVE-Bridge + Copyright (C) 2023 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 + . */ + +#ifndef DEF_NEON_SVE_FUNCTION +#define DEF_NEON_SVE_FUNCTION(A, B, C, D) +#endif + +DEF_NEON_SVE_FUNCTION (svset_neonq, set_neonq, all_data, none) +DEF_NEON_SVE_FUNCTION (svget_neonq, get_neonq, all_data, none) +DEF_NEON_SVE_FUNCTION (svdup_neonq, dup_neonq, all_data, none) + +#undef DEF_NEON_SVE_FUNCTION \ No newline at end of file diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 70303d6fd953e0c397b9138ede8858c2db2e53db..c5e4e20e73cedb363d867a73869c0659ed9b237d 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -987,6 +987,7 @@ void handle_arm_neon_h (void); namespace aarch64_sve { void init_builtins (); void handle_arm_sve_h (); + void handle_arm_neon_sve_bridge_h (); tree builtin_decl (unsigned, bool); bool builtin_type_p (const_tree); bool builtin_type_p (const_tree, unsigned int *, unsigned int *); diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.h b/gcc/config/aarch64/aarch64-sve-builtins-base.h index d300e3a85d00b58ad790851a81d43af709b66bce..df75e4c1ecf81f3ddfa256edbcf8637d092fcfde 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-base.h +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.h @@ -299,6 +299,12 @@ namespace aarch64_sve extern const function_base *const svzip2; extern const function_base *const svzip2q; } + namespace neon_sve_bridge_functions + { + extern const function_base *const svset_neonq; + extern const function_base *const svget_neonq; + extern const function_base *const svdup_neonq; + } } #endif diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc index 9010ecca6da23c107f5ded9ab3cfa678e308daf9..0acc3acf7d34b54af8679dc36effb85f7b557543 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc @@ -44,6 +44,7 @@ #include "aarch64-sve-builtins-shapes.h" #include "aarch64-sve-builtins-base.h" #include "aarch64-sve-builtins-functions.h" +#include "aarch64-builtins.h" #include "ssa.h" #include "gimple-fold.h" @@ -1064,6 +1065,99 @@ public: } }; +class svget_neonq_impl : public function_base +{ +public: + gimple * + fold (gimple_folder &f) const override + { + tree rhs_tuple = gimple_call_arg (f.call, 0); + tree rhs_vector = build3 (BIT_FIELD_REF, TREE_TYPE (f.lhs), + rhs_tuple, bitsize_int(128), bitsize_int(0)); + return gimple_build_assign (f.lhs, rhs_vector); + } + rtx + expand (function_expander &e) const override + { + return simplify_gen_subreg (e.vector_mode (0), e.args[0], + GET_MODE (e.args[0]), + INTVAL (e.args[1]) * BYTES_PER_SVE_VECTOR); + } +}; + +class svset_neonq_impl : public function_base +{ +public: + gimple * + fold (gimple_folder &f) const override + { + tree rhs_tuple = gimple_call_arg (f.call, 0); + tree rhs_vector = gimple_call_arg (f.call, 1); + gassign *copy = gimple_build_assign (unshare_expr (f.lhs), rhs_tuple); + tree lhs_vector = build3 (BIT_INSERT_EXPR, TREE_TYPE (rhs_vector), + f.lhs, rhs_vector, bitsize_int(0)); + gassign *update = gimple_build_assign (f.lhs, lhs_vector); + gsi_insert_after (f.gsi, update, GSI_SAME_STMT); + return copy; + } + rtx + expand (function_expander &e) const override + { + rtx rhs_tuple = e.args[0]; + unsigned int index = INTVAL (e.args[1]); + rtx rhs_vector = e.args[2]; + rtx lhs_tuple = e.get_nonoverlapping_reg_target (); + emit_move_insn (lhs_tuple, rhs_tuple); + rtx lhs_vector = simplify_gen_subreg (GET_MODE (rhs_vector), + lhs_tuple, GET_MODE (lhs_tuple), + index * BYTES_PER_SVE_VECTOR); + emit_move_insn (lhs_vector, rhs_vector); + return lhs_vector; + } +}; + +class svdup_neonq_impl : public function_base +{ +public: + gimple * + fold (gimple_folder &f) const override + { + tree rhs_vector = gimple_call_arg (f.call, 0); + unsigned int nargs = gimple_call_num_args (f.call); + unsigned HOST_WIDE_INT NEONnelts; + TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs_vector)).is_constant (&NEONnelts); + poly_uint64 SVEnelts; + SVEnelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (f.lhs)); + vec_perm_builder builder (SVEnelts, NEONnelts, 1); + for (unsigned int i = 0; i < NEONnelts; i++) + { + builder.quick_push (i); + } + vec_perm_indices indices (builder, 1, NEONnelts); + tree perm_type = build_vector_type (ssizetype, SVEnelts); + return gimple_build_assign (f.lhs, VEC_PERM_EXPR, + rhs_vector, + rhs_vector, + vec_perm_indices_to_tree (perm_type, indices)); + } + rtx + expand (function_expander &e) const override + { + insn_code icode; + machine_mode mode = e.vector_mode (0); + if (valid_for_const_vector_p (GET_MODE_INNER (mode), e.args.last ())) + /* Duplicate the constant to fill a vector. The pattern optimizes + various cases involving constant operands, falling back to SEL + if necessary. */ + icode = code_for_vcond_mask (mode, mode); + else + /* Use the pattern for selecting between a duplicated scalar + variable and a vector fallback. */ + icode = code_for_aarch64_sel_dup (mode); + return e.use_vcond_mask_insn (icode); + } +}; + class svindex_impl : public function_base { public: @@ -3028,5 +3122,8 @@ FUNCTION (svzip1q, unspec_based_function, (UNSPEC_ZIP1Q, UNSPEC_ZIP1Q, FUNCTION (svzip2, svzip_impl, (1)) FUNCTION (svzip2q, unspec_based_function, (UNSPEC_ZIP2Q, UNSPEC_ZIP2Q, UNSPEC_ZIP2Q)) +NEON_SVE_BRIDGE_FUNCTION (svget_neonq, svget_neonq_impl,) +NEON_SVE_BRIDGE_FUNCTION (svset_neonq, svset_neonq_impl,) +NEON_SVE_BRIDGE_FUNCTION (svdup_neonq, svdup_neonq_impl,) } /* end namespace aarch64_sve */ diff --git a/gcc/config/aarch64/aarch64-sve-builtins-functions.h b/gcc/config/aarch64/aarch64-sve-builtins-functions.h index 2729877d914414eff33182e03ab1dfc94a3515fa..bfb7fea674a905a2eb99f2bac7cbcb72af681b52 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-functions.h +++ b/gcc/config/aarch64/aarch64-sve-builtins-functions.h @@ -622,4 +622,8 @@ public: namespace { static CONSTEXPR const CLASS NAME##_obj ARGS; } \ namespace functions { const function_base *const NAME = &NAME##_obj; } +#define NEON_SVE_BRIDGE_FUNCTION(NAME, CLASS, ARGS) \ + namespace { static CONSTEXPR const CLASS NAME##_obj ARGS; } \ + namespace neon_sve_bridge_functions { const function_base *const NAME = &NAME##_obj; } + #endif diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.h b/gcc/config/aarch64/aarch64-sve-builtins-shapes.h index 7483c1d04b8e463e607e8e65aa94233460f77648..30c0bf8503622b0320a334b79c328233248122a4 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.h +++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.h @@ -186,6 +186,13 @@ namespace aarch64_sve extern const function_shape *const unary_uint; extern const function_shape *const unary_widen; } + + namespace neon_sve_bridge_shapes + { + extern const function_shape *const get_neonq; + extern const function_shape *const set_neonq; + extern const function_shape *const dup_neonq; + } } #endif diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc index af816c4c9e705d9cc4bce5cc50481cb27e6a03a7..46e65cc78b3cf7bb70344a856c8fdb481534f46c 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc @@ -29,6 +29,7 @@ #include "optabs.h" #include "aarch64-sve-builtins.h" #include "aarch64-sve-builtins-shapes.h" +#include "aarch64-builtins.h" /* In the comments below, _t0 represents the first type suffix and _t1 represents the second. Square brackets enclose characters that are @@ -145,6 +146,76 @@ parse_element_type (const function_instance &instance, const char *&format) gcc_unreachable (); } +int +parse_neon_type (type_suffix_index suffix, int ch) +{ + if (ch == 'Q') + { + switch (suffix) + { + case TYPE_SUFFIX_s8: + return Int8x16_t; + case TYPE_SUFFIX_s16: + return Int16x8_t; + case TYPE_SUFFIX_s32: + return Int32x4_t; + case TYPE_SUFFIX_s64: + return Int64x2_t; + case TYPE_SUFFIX_u8: + return Uint8x16_t; + case TYPE_SUFFIX_u16: + return Uint16x8_t; + case TYPE_SUFFIX_u32: + return Uint32x4_t; + case TYPE_SUFFIX_u64: + return Uint64x2_t; + case TYPE_SUFFIX_f16: + return Float16x8_t; + case TYPE_SUFFIX_f32: + return Float32x4_t; + case TYPE_SUFFIX_f64: + return Float64x2_t; + case TYPE_SUFFIX_bf16: + return Bfloat16x8_t; + default: + gcc_unreachable (); + } + } + if (ch == 'D') + { + switch (suffix) + { + case TYPE_SUFFIX_s8: + return Int8x8_t; + case TYPE_SUFFIX_s16: + return Int16x4_t; + case TYPE_SUFFIX_s32: + return Int32x2_t; + case TYPE_SUFFIX_s64: + return Int64x1_t; + case TYPE_SUFFIX_u8: + return Uint8x8_t; + case TYPE_SUFFIX_u16: + return Uint16x4_t; + case TYPE_SUFFIX_u32: + return Uint32x2_t; + case TYPE_SUFFIX_u64: + return Uint64x1_t; + case TYPE_SUFFIX_f16: + return Float16x4_t; + case TYPE_SUFFIX_f32: + return Float32x2_t; + case TYPE_SUFFIX_f64: + return Float64x1_t; + case TYPE_SUFFIX_bf16: + return Bfloat16x4_t; + default: + gcc_unreachable (); + } + } + gcc_unreachable (); +} + /* Read and return a type from FORMAT for function INSTANCE. Advance FORMAT beyond the type string. The format is: @@ -158,6 +229,8 @@ parse_element_type (const function_instance &instance, const char *&format) s - a scalar type with the given element suffix t - a vector or tuple type with given element suffix [*1] v - a vector with the given element suffix + D - a 64 bit neon vector + Q - a 128 bit neon vector where has the format described above parse_element_type @@ -224,6 +297,13 @@ parse_type (const function_instance &instance, const char *&format) return acle_vector_types[0][type_suffixes[suffix].vector_type]; } + if (ch == 'Q' || ch == 'D') + { + type_suffix_index suffix = parse_element_type (instance, format); + int neon_index = parse_neon_type (suffix, ch); + return aarch64_simd_types[neon_index].itype; + } + gcc_unreachable (); } @@ -450,6 +530,12 @@ long_type_suffix (function_resolver &r, type_suffix_index type) static CONSTEXPR const NAME##_def NAME##_obj; \ namespace shapes { const function_shape *const NAME = &NAME##_obj; } +/* Declare the function neon_sve_bridge_shape NAME, pointing it to an instance + of class _def. */ +#define NEON_SVE_BRIDGE_SHAPE(NAME) \ + static CONSTEXPR const NAME##_def NAME##_obj; \ + namespace neon_sve_bridge_shapes { const function_shape *const NAME = &NAME##_obj; } + /* Base class for functions that are not overloaded. */ struct nonoverloaded_base : public function_shape { @@ -1917,6 +2003,72 @@ struct get_def : public overloaded_base<0> }; SHAPE (get) +/* xN_t svfoo[_t0](sv_t). */ +struct get_neonq_def : public overloaded_base<0> +{ + void + build (function_builder &b, const function_group_info &group) const override + { + b.add_overloaded_functions (group, MODE_none); + build_all (b, "Q0,v0", group, MODE_none); + } + tree + resolve (function_resolver &r) const override + { + unsigned int i, nargs; + type_suffix_index type; + if (!r.check_gp_argument (1, i, nargs) + || (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES) + return error_mark_node; + return r.resolve_to (r.mode_suffix_id, type); + } +}; +NEON_SVE_BRIDGE_SHAPE (get_neonq) + +/* sv_t svfoo[_t0](sv_t, xN_t). */ +struct set_neonq_def : public overloaded_base<0> +{ + void + build (function_builder &b, const function_group_info &group) const override + { + b.add_overloaded_functions (group, MODE_none); + build_all (b, "v0,v0,Q0", group, MODE_none); + } + tree + resolve (function_resolver &r) const override + { + unsigned int i, nargs; + type_suffix_index type; + if (!r.check_gp_argument (1, i, nargs) + || (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES) + return error_mark_node; + return r.resolve_to (r.mode_suffix_id, type); + } +}; +NEON_SVE_BRIDGE_SHAPE (set_neonq) + +/* sv_t svfoo[_t0](xN_t). */ +struct dup_neonq_def : public overloaded_base<0> +{ + void + build (function_builder &b, const function_group_info &group) const override + { + b.add_overloaded_functions (group, MODE_none); + build_all (b, "v0,Q0", group, MODE_none); + } + tree + resolve (function_resolver &r) const override + { + unsigned int i, nargs; + type_suffix_index type; + if (!r.check_gp_argument (1, i, nargs) + || (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES) + return error_mark_node; + return r.resolve_to (r.mode_suffix_id, type); + } +}; +NEON_SVE_BRIDGE_SHAPE (dup_neonq) + /* sv_t svfoo[_t0](sv_t, uint64_t) _t svfoo[_n_t0](_t, uint64_t) diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 161a14edde7c9fb1b13b146cf50463e2d78db264..c994c83c5777e500ab2cf76ee2ed29dcebca074f 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -529,6 +529,13 @@ static CONSTEXPR const function_group_info function_groups[] = { #include "aarch64-sve-builtins.def" }; +/* A list of all NEON-SVE-Bridge ACLE functions. */ +static CONSTEXPR const function_group_info neon_sve_function_groups[] = { +#define DEF_NEON_SVE_FUNCTION(NAME, SHAPE, TYPES, PREDS) \ + { #NAME, &neon_sve_bridge_functions::NAME, &neon_sve_bridge_shapes::SHAPE, types_##TYPES, preds_##PREDS }, +#include "aarch64-neon-sve-bridge-builtins.def" +}; + /* The scalar type associated with each vector type. */ extern GTY(()) tree scalar_types[NUM_VECTOR_TYPES]; tree scalar_types[NUM_VECTOR_TYPES]; @@ -3560,6 +3567,20 @@ handle_arm_sve_h () builder.register_function_group (function_groups[i]); } +/* Implement #pragma GCC aarch64 "arm_sve.h". */ +void +handle_arm_neon_sve_bridge_h () +{ + + sve_switcher sve; + + /* Define the functions. */ + function_table = new hash_table (1023); + function_builder builder; + for (unsigned int i = 0; i < ARRAY_SIZE (neon_sve_function_groups); ++i) + builder.register_function_group (neon_sve_function_groups[i]); +} + /* Return the function decl with SVE function subcode CODE, or error_mark_node if no such function exists. */ tree diff --git a/gcc/config/aarch64/arm_neon_sve_bridge.h b/gcc/config/aarch64/arm_neon_sve_bridge.h new file mode 100644 index 0000000000000000000000000000000000000000..8f526eae86b94f615d22fe8de52583bb403e102e --- /dev/null +++ b/gcc/config/aarch64/arm_neon_sve_bridge.h @@ -0,0 +1,38 @@ +/* AArch64 NEON-SVE Bridge intrinsics include file. + Copyright (C) 2023 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 + . */ + +#ifndef _ARM_NEON_SVE_BRIDGE_H_ +#define _ARM_NEON_SVE_BRIDGE_H_ + +#include +#include + +/* NOTE: This implementation of arm_neon_sve_bridge.h is intentionally short. It does + not define the types and intrinsic functions directly in C and C++ + code, but instead uses the following pragma to tell GCC to insert the + necessary type and function definitions itself. The net effect is the + same, and the file is a complete implementation of arm_neon_sve_bridge.h. */ +#pragma GCC aarch64 "arm_neon_sve_bridge.h" + +#endif \ No newline at end of file diff --git a/gcc/testsuite/gcc.c-torture/execute/neon-sve-bridge.c b/gcc/testsuite/gcc.c-torture/execute/neon-sve-bridge.c new file mode 100644 index 0000000000000000000000000000000000000000..45dbcf97a647f0842693dbe47eedb4264e7b61fd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/neon-sve-bridge.c @@ -0,0 +1,55 @@ +// { dg-options "-march=armv8.2-a+sve" } +// { dg-do run { target aarch64_sve_hw } } + +#include + +extern void abort (void); + +int +svget_neonq_test () +{ + int64_t val1 = 987654321; + svint64_t sveInput = svdup_n_s64(val1); + int64x2_t neonReturn = svget_neonq_s64 (sveInput); + int64_t val1Return = vgetq_lane_s64(neonReturn, 1); + if (val1 == val1Return) + return 0; + return 1; +} + +int +svset_neonq_test () +{ + int64_t val2 = 123456789; + int64x2_t NeonInput = vdupq_n_s64(val2); + svint64_t sveReturn; + sveReturn = svset_neonq_s64 (sveReturn, NeonInput); + int64_t val2Return = svlasta_s64(svptrue_b64(), sveReturn); + if (val2 == val2Return) + return 0; + return 1; +} + +int +svdup_neonq_test () +{ + uint32_t val2 = 123456789; + uint32x4_t NeonInput = vdupq_n_u32(val2); + svuint32_t sveReturn = svdup_neonq_u32 (NeonInput); + uint32_t val2Return = svlastb_u32(svptrue_b32(), sveReturn); + if (val2 == val2Return) + return 0; + return 1; +} + +int +main () +{ + if (svget_neonq_test() == 1) + abort (); + if (svset_neonq_test() == 1) + abort (); + if (svdup_neonq_test() == 1) + abort (); + return 0; +} \ No newline at end of file