From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 35619 invoked by alias); 14 Nov 2019 19:13:24 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 35519 invoked by uid 89); 14 Nov 2019 19:13:23 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.4 required=5.0 tests=AWL,BAYES_00,FORGED_SPF_HELO,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LOTSOFHASH,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,URI_NOVOWEL autolearn=ham version=3.3.1 spammy= X-HELO: EUR04-HE1-obe.outbound.protection.outlook.com Received: from mail-eopbgr70089.outbound.protection.outlook.com (HELO EUR04-HE1-obe.outbound.protection.outlook.com) (40.107.7.89) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 14 Nov 2019 19:13:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BRN18LecOKiVdLcYEiQSbbtZIgypBszPFCbaaYsWuxI=; b=I+D09EthC8ySQCtB0FdAJOi+23Dl73iI6jhDrIbU6IYByYUKLrFvi6VmIZOjzwyFvxK0LX4TipSHTpAM+6bOomHmpsIGv/pxyyskkikiWrfHZmDjeSkWXPwM1vewsogw0m25d8GS/4VY7ibK0vxyqk/sL+W3Sskh4UVycsQFeyY= Received: from VI1PR08CA0098.eurprd08.prod.outlook.com (2603:10a6:800:d3::24) by AM6PR08MB3495.eurprd08.prod.outlook.com (2603:10a6:20b:48::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2430.25; Thu, 14 Nov 2019 19:13:05 +0000 Received: from AM5EUR03FT037.eop-EUR03.prod.protection.outlook.com (2a01:111:f400:7e08::207) by VI1PR08CA0098.outlook.office365.com (2603:10a6:800:d3::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2451.23 via Frontend Transport; Thu, 14 Nov 2019 19:13:05 +0000 Authentication-Results: spf=fail (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; gcc.gnu.org; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;gcc.gnu.org; dmarc=none action=none header.from=arm.com; Received-SPF: Fail (protection.outlook.com: domain of arm.com does not designate 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM5EUR03FT037.mail.protection.outlook.com (10.152.17.241) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2451.23 via Frontend Transport; Thu, 14 Nov 2019 19:13:04 +0000 Received: ("Tessian outbound e4042aced47b:v33"); Thu, 14 Nov 2019 19:13:04 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 28126f8930483d96 X-CR-MTA-TID: 64aa7808 Received: from 81e77393c94a.1 (cr-mta-lb-1.cr-mta-net [104.47.10.50]) by 64aa7808-outbound-1.mta.getcheckrecipient.com id 4E651DAC-FF07-4AF6-B561-B36420CA2E09.1; Thu, 14 Nov 2019 19:12:59 +0000 Received: from EUR03-DB5-obe.outbound.protection.outlook.com (mail-db5eur03lp2050.outbound.protection.outlook.com [104.47.10.50]) by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 81e77393c94a.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 14 Nov 2019 19:12:59 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=GQk3r+0EpYDtcE7UfTlWlSlsK8YYqFz9mSZH7rbNNY1l/jjhddXtWgh2Vr+d3ankBN0EFcNckpngD0xruG2a+0S024hU2yVser4etdHtGboM0y2BEVf6Fcy89hxwusVxItyKz/4zU4jf6mucE4c3H1dZOWXvTnBP+6Zuc6wEmX9Z9ay7mw9ENK2QnIejwCZ/wjUi9ue7fCqWOK9keFuNEx/4kYEABd0ZBsk6V+ueKwDT2qPy1XMxivq0KaW2yeLZfxNK9sWmAe3h2BrXTGB04POxF//yobwvHUunyvdiLezDQ+b6pofOW4E+/9aJrRfxjOKc2HX3iDdifCbPhMlosQ== 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-SenderADCheck; bh=BRN18LecOKiVdLcYEiQSbbtZIgypBszPFCbaaYsWuxI=; b=c74eC9Diwew5gMlTQ86pc3083Wi29gy6ITZT5z17LRkxhQf34pRUF/nrEROeuRCjax7mmbJS/3VWT1qK5cWX17epENkXASqgT+/L/HmP+W779T7aOyKMWk8pg4jDhCYh9UfFfTiNWLOqyLS+7Rl14ydhanXrGIwryFW3a94HQ2VRycmfZYlLvJ4Ral4OVFj04PUntU/mxvGo4iR80mKUOo1rsg0psNx7f/3wKhbdvNGMm9aec3oOC8Fd5Rdgyfzpe3o5cYyPHOSNY0WtNVuZfKZDykDg1qT/j4slpYfa4vflKyNjE3fhCoqRMuO+zFfxQQ06fcgdxIJkfHoqgBoAeg== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BRN18LecOKiVdLcYEiQSbbtZIgypBszPFCbaaYsWuxI=; b=I+D09EthC8ySQCtB0FdAJOi+23Dl73iI6jhDrIbU6IYByYUKLrFvi6VmIZOjzwyFvxK0LX4TipSHTpAM+6bOomHmpsIGv/pxyyskkikiWrfHZmDjeSkWXPwM1vewsogw0m25d8GS/4VY7ibK0vxyqk/sL+W3Sskh4UVycsQFeyY= Received: from DBBPR08MB4775.eurprd08.prod.outlook.com (20.179.46.211) by DBBPR08MB4631.eurprd08.prod.outlook.com (10.255.78.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2430.24; Thu, 14 Nov 2019 19:12:55 +0000 Received: from DBBPR08MB4775.eurprd08.prod.outlook.com ([fe80::1c7c:c72d:2183:12d1]) by DBBPR08MB4775.eurprd08.prod.outlook.com ([fe80::1c7c:c72d:2183:12d1%7]) with mapi id 15.20.2430.028; Thu, 14 Nov 2019 19:12:55 +0000 From: Srinath Parvathaneni To: "gcc-patches@gcc.gnu.org" CC: Richard Earnshaw , Kyrylo Tkachov Subject: [PATCH][ARM][GCC][1/x]: MVE ACLE intrinsics framework patch. Date: Thu, 14 Nov 2019 19:16:00 -0000 Message-ID: References: <157375666998.31400.16652205595246718910.scripted-patch-series@arm.com> In-Reply-To: <157375666998.31400.16652205595246718910.scripted-patch-series@arm.com> Authentication-Results-Original: spf=none (sender IP is ) smtp.mailfrom=Srinath.Parvathaneni@arm.com; X-MS-Exchange-PUrlCount: 2 x-ms-exchange-transport-forked: True x-checkrecipientrouted: true x-ms-oob-tlc-oobclassifiers: OLM:8882;OLM:8882; X-Forefront-Antispam-Report-Untrusted: SFV:NSPM;SFS:(10009020)(4636009)(346002)(39860400002)(366004)(136003)(376002)(396003)(189003)(199004)(54534003)(76176011)(81166006)(86362001)(55016002)(9686003)(54906003)(26005)(2906002)(6306002)(102836004)(6436002)(5640700003)(7736002)(2351001)(44832011)(186003)(6506007)(6116002)(71200400001)(3846002)(2501003)(386003)(5660300002)(71190400001)(99286004)(486006)(476003)(7696005)(6916009)(478600001)(52116002)(74316002)(52536014)(33656002)(8676002)(66556008)(30864003)(81156014)(25786009)(66066001)(966005)(256004)(14444005)(4001150100001)(66616009)(64756008)(316002)(4326008)(305945005)(446003)(66946007)(66446008)(11346002)(5024004)(8936002)(14454004)(66476007)(2004002)(569006);DIR:OUT;SFP:1101;SCL:1;SRVR:DBBPR08MB4631;H:DBBPR08MB4775.eurprd08.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: mvhzhLLg1B28BPHOCMPq4bcT1O7+xs9UM0mEaXTBLb3BF4hLaUZzmbxpXOi5BqUG6E70sSZEhMyEpyPY8z9yVIzfR6rOH/3ug2vYvEjmOcBTAT9Sq8RBqvIDOLVZPZNOolx9owosSnbCFLnvLy1FcIf3m9+u3JQqK+yr/t1HJsgDsk7fmxJOHdQ/KJXt8sKfL/aXUsIZ1qOqdybuvs8T6PXZPa0f4iX9er9ZEHrz8iUCF1QW/MAVPTLT7cCkv3R4jXiqBhCsbUNJkcpFa6F4UuXJlmjoSo5Ro6imHdVrjEzKrP4GLdW+6EQVCelMD5xC7oULKWzPu+4CuOhEZnu6l4Hp5NUS9u19eLiHoxvb+v0QnMKmY4RUUe2ltLssX5pGIqd1szEQwPR4ELdIHUlwmPNt7kIrEybryQ+PRjl5xHD3p/L7ff0pb+H1pOKYRus0tqn/gAQExqD2arjaRMqH1IHgPWu2xGSzHZ526lNrk7U= Content-Type: multipart/mixed; boundary="_002_DBBPR08MB4775F9F4A174B7BFD2021C9C9B710DBBPR08MB4775eurp_" MIME-Version: 1.0 Original-Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Srinath.Parvathaneni@arm.com; Return-Path: Srinath.Parvathaneni@arm.com X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM5EUR03FT037.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: 99d934f4-5153-45f0-a762-08d76936a6db X-IsSubscribed: yes X-SW-Source: 2019-11/txt/msg01280.txt.bz2 --_002_DBBPR08MB4775F9F4A174B7BFD2021C9C9B710DBBPR08MB4775eurp_ Content-Type: text/plain; charset="us-ascii" Content-ID: Content-Transfer-Encoding: quoted-printable Content-length: 73649 Hello, This patch creates the required framework for MVE ACLE intrinsics. The following changes are done in this patch to support MVE ACLE intrinsics. Header file arm_mve.h is added to source code, which contains the definitio= ns of MVE ACLE intrinsics and different data types used in MVE. Machine description file mve.md is al= so added which contains the RTL patterns defined for MVE. A new reigster "p0" is added which is used in by MVE predicated patterns. A= new register class "VPR_REG" is added and its contents are defined in REG_CLASS_CONTENTS. The vec-common.md file is modified to support the standard move patterns. T= he prefix of neon functions which are also used by MVE is changed from "neon_" to "simd_". eg: neon_immediate_valid_for_move changed to simd_immediate_valid_for_move. In the patch standard patterns mve_move, mve_store and move_load for MVE ar= e added and neon.md and vfp.md files are modified to support this common patterns. Please refer to Arm reference manual [1] for more details. [1] https://static.docs.arm.com/ddi0553/bh/DDI0553B_h_armv8m_arm.pdf?_ga=3D= 2.102521798.659307368.1572453718-1501600630.1548848914 Regression tested on arm-none-eabi and found no regressions. Ok for trunk? Thanks, Srinath gcc/ChangeLog: 2019-11-11 Andre Vieira Mihail Ionescu Srinath Parvathaneni * config.gcc (arm_mve.h): Add header file. * config/arm/aout.h (p0): Add new register name. * config/arm-builtins.c (ARM_BUILTIN_SIMD_LANE_CHECK): Define. (ARM_BUILTIN_NEON_LANE_CHECK): Remove. (arm_init_simd_builtin_types): Add TARGET_HAVE_MVE check. (arm_init_neon_builtins): Move a check to arm_init_builtins function. (arm_init_builtins): Move a check from arm_init_neon_builtins function. (mve_dereference_pointer): Add new function. (arm_expand_builtin_args): Add TARGET_HAVE_MVE check. (arm_expand_neon_builtin): Move a check to arm_expand_builtin function. (arm_expand_builtin): Move a check from arm_expand_neon_builtin function. * config/arm/arm-c.c (arm_cpu_builtins): Define macros for MVE. * config/arm/arm-modes.def (INT_MODE): Add three new integer modes. * config/arm/arm-protos.h (neon_immediate_valid_for_move): Rename function. (simd_immediate_valid_for_move): Rename neon_immediate_valid_for_move func= tion. * config/arm/arm.c (arm_options_perform_arch_sanity_checks):Enable mve isa= bit. (use_return_insn): Add TARGET_HAVE_MVE check. (aapcs_vfp_allocate): Add TARGET_HAVE_MVE check. (aapcs_vfp_allocate_return_reg): Add TARGET_HAVE_MVE check. (thumb2_legitimate_address_p): Add TARGET_HAVE_MVE check. (arm_rtx_costs_internal): Add TARGET_HAVE_MVE check. (neon_valid_immediate): Rename to simd_valid_immediate. (simd_valid_immediate): Rename from neon_valid_immediate. (neon_immediate_valid_for_move): Rename to simd_immediate_valid_for_move. (simd_immediate_valid_for_move): Rename from neon_immediate_valid_for_move. (neon_immediate_valid_for_logic): Modify call to neon_valid_immediate func= tion. (neon_make_constant): Modify call to neon_valid_immediate function. (neon_vector_mem_operand): Add TARGET_HAVE_MVE check. (output_move_neon): Add TARGET_HAVE_MVE check. (arm_compute_frame_layout): Add TARGET_HAVE_MVE check. (arm_save_coproc_regs): Add TARGET_HAVE_MVE check. (arm_print_operand): Add case 'E' to print memory operands. (arm_print_operand_address): Add TARGET_HAVE_MVE check. (arm_hard_regno_mode_ok): Add TARGET_HAVE_MVE check. (arm_modes_tieable_p): Add TARGET_HAVE_MVE check. (arm_regno_class): Add VPR_REGNUM check. (arm_expand_epilogue_apcs_frame): Add TARGET_HAVE_MVE check. (arm_expand_epilogue): Add TARGET_HAVE_MVE check. (arm_vector_mode_supported_p): Add TARGET_HAVE_MVE check for MVE vector mo= des. (arm_array_mode_supported_p): Add TARGET_HAVE_MVE check. (arm_conditional_register_usage): For TARGET_HAVE_MVE enable VPR register. * config/arm/arm.h (IS_VPR_REGNUM): Macro to check for VPR register. (FIRST_PSEUDO_REGISTER): Modify. (VALID_MVE_MODE): Define. (VALID_MVE_SI_MODE): Define. (VALID_MVE_SF_MODE): Define. (VALID_MVE_STRUCT_MODE): Define. (REG_ALLOC_ORDER): Add VPR_REGNUM entry. (enum reg_class): Add VPR_REG entry. (REG_CLASS_NAMES): Add VPR_REG entry. * config/arm/arm.md (VPR_REGNUM): Define. (arm_movsf_soft_insn): Add TARGET_HAVE_MVE check to not allow MVE. (vfp_pop_multiple_with_writeback): Add TARGET_HAVE_MVE check to allow writ= eback. (include "mve.md"): Include mve.md file. * config/arm/arm_mve.h: New file. * config/arm/constraints.md (Up): Define. * config/arm/iterators.md (VNIM1): Define. (VNINOTM1): Define. (VSTRUCT): Modify. * config/arm/mve.md: New file. * config/arm/neon.md: (mov): Add TARGET_HAVE_MVE check. (movv4hf): Define. (neon_mov): Add TARGET_HAVE_MVE check. (define_split): Add TARGET_HAVE_MVE check. (vec_init): Add TARGET_HAVE_MVE check. * config/arm/predicates.md (vpr_register_operand): Define. * config/arm/t-arm: Add mve.md file. * config/arm/types.md: Add MVE instructions mve_move, mve_load, mve_store. * config/arm/vec-common.md (mov): Add TARGET_HAVE_MVE check. (mov): Modify iterator. (movv8hf): Define gcc/testsuite/ChangeLog: 2019-11-11 Andre Vieira Mihail Ionescu Srinath Parvathaneni * gcc.target/arm/mve/intrinsics/mve_vector_float.c: New test. * gcc.target/arm/mve/intrinsics/mve_vector_float1.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_vector_float2.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_vector_int.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_vector_int1.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_vector_int2.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_vector_uint.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_vector_uint1.c: Likewise. * gcc.target/arm/mve/intrinsics/mve_vector_uint2.c: Likewise. * gcc.target/arm/mve/mve.exp: New file. ############### Attachment also inlined for ease of reply ##########= ##### diff --git a/gcc/config.gcc b/gcc/config.gcc index 72f656408f11802c669c3de953bf3020020ca312..c4a7d984936c531d7dfcce347d5= 6b5931913e68b 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -344,7 +344,7 @@ arc*-*-*) arm*-*-*) cpu_type=3Darm extra_objs=3D"arm-builtins.o aarch-common.o" - extra_headers=3D"mmintrin.h arm_neon.h arm_acle.h arm_fp16.h arm_cmse.h" + extra_headers=3D"mmintrin.h arm_neon.h arm_acle.h arm_fp16.h arm_cmse.h a= rm_mve.h" target_type_format_char=3D'%' c_target_objs=3D"arm-c.o" cxx_target_objs=3D"arm-c.o" diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h index 72782758853a869bcb9a9d69f3fa0da979cd711f..28cde153f704748f35c84d072b5= 9e9695a61e661 100644 --- a/gcc/config/arm/aout.h +++ b/gcc/config/arm/aout.h @@ -53,7 +53,9 @@ /* The assembler's names for the registers. Note that the ?xx registers a= re there so that VFPv3/NEON registers D16-D31 have the same spacing as D0-= D15 (each of which is overlaid on two S registers), although there are no - actual single-precision registers which correspond to D16-D31. */ + actual single-precision registers which correspond to D16-D31. New reg= ister + p0 is added which is used for MVE predicated cases. */ + #ifndef REGISTER_NAMES #define REGISTER_NAMES \ { \ @@ -72,7 +74,7 @@ "wr8", "wr9", "wr10", "wr11", \ "wr12", "wr13", "wr14", "wr15", \ "wcgr0", "wcgr1", "wcgr2", "wcgr3", \ - "cc", "vfpcc", "sfp", "afp", "apsrq", "apsrge" \ + "cc", "vfpcc", "sfp", "afp", "apsrq", "apsrge", "p0" \ } #endif =20 diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c index 650b22c7ad916d9abd587981e9ed5809755ee035..d4cb0ea3deb49b10266d1620c85= e243ed34aee4d 100644 --- a/gcc/config/arm/arm-builtins.c +++ b/gcc/config/arm/arm-builtins.c @@ -667,6 +667,7 @@ enum arm_builtins ARM_BUILTIN_SET_FPSCR, =20 ARM_BUILTIN_CMSE_NONSECURE_CALLER, + ARM_BUILTIN_SIMD_LANE_CHECK, =20 #undef CRYPTO1 #undef CRYPTO2 @@ -692,7 +693,6 @@ enum arm_builtins #include "arm_vfp_builtins.def" =20 ARM_BUILTIN_NEON_BASE, - ARM_BUILTIN_NEON_LANE_CHECK =3D ARM_BUILTIN_NEON_BASE, =20 #include "arm_neon_builtins.def" =20 @@ -948,26 +948,35 @@ arm_init_simd_builtin_types (void) an entry in our mangling table, consequently, they get default mangling. As a further gotcha, poly8_t and poly16_t are signed types, poly64_t and poly128_t are unsigned types. */ - arm_simd_polyQI_type_node - =3D build_distinct_type_copy (intQI_type_node); - (*lang_hooks.types.register_builtin_type) (arm_simd_polyQI_type_node, - "__builtin_neon_poly8"); - arm_simd_polyHI_type_node - =3D build_distinct_type_copy (intHI_type_node); - (*lang_hooks.types.register_builtin_type) (arm_simd_polyHI_type_node, - "__builtin_neon_poly16"); - arm_simd_polyDI_type_node - =3D build_distinct_type_copy (unsigned_intDI_type_node); - (*lang_hooks.types.register_builtin_type) (arm_simd_polyDI_type_node, - "__builtin_neon_poly64"); - arm_simd_polyTI_type_node - =3D build_distinct_type_copy (unsigned_intTI_type_node); - (*lang_hooks.types.register_builtin_type) (arm_simd_polyTI_type_node, - "__builtin_neon_poly128"); - /* Prevent front-ends from transforming poly vectors into string - literals. */ - TYPE_STRING_FLAG (arm_simd_polyQI_type_node) =3D false; - TYPE_STRING_FLAG (arm_simd_polyHI_type_node) =3D false; + if (!TARGET_HAVE_MVE) + { + arm_simd_polyQI_type_node + =3D build_distinct_type_copy (intQI_type_node); + (*lang_hooks.types.register_builtin_type) (arm_simd_polyQI_type_node, + "__builtin_neon_poly8"); + arm_simd_polyHI_type_node + =3D build_distinct_type_copy (intHI_type_node); + (*lang_hooks.types.register_builtin_type) (arm_simd_polyHI_type_node, + "__builtin_neon_poly16"); + arm_simd_polyDI_type_node + =3D build_distinct_type_copy (unsigned_intDI_type_node); + (*lang_hooks.types.register_builtin_type) (arm_simd_polyDI_type_node, + "__builtin_neon_poly64"); + arm_simd_polyTI_type_node + =3D build_distinct_type_copy (unsigned_intTI_type_node); + (*lang_hooks.types.register_builtin_type) (arm_simd_polyTI_type_node, + "__builtin_neon_poly128"); + /* Init poly vector element types with scalar poly types. */ + arm_simd_types[Poly8x8_t].eltype =3D arm_simd_polyQI_type_node; + arm_simd_types[Poly8x16_t].eltype =3D arm_simd_polyQI_type_node; + arm_simd_types[Poly16x4_t].eltype =3D arm_simd_polyHI_type_node; + arm_simd_types[Poly16x8_t].eltype =3D arm_simd_polyHI_type_node; + + /* Prevent front-ends from transforming poly vectors into string + literals. */ + TYPE_STRING_FLAG (arm_simd_polyQI_type_node) =3D false; + TYPE_STRING_FLAG (arm_simd_polyHI_type_node) =3D false; + } =20 /* Init all the element types built by the front-end. */ arm_simd_types[Int8x8_t].eltype =3D intQI_type_node; @@ -985,11 +994,6 @@ arm_init_simd_builtin_types (void) arm_simd_types[Uint32x4_t].eltype =3D unsigned_intSI_type_node; arm_simd_types[Uint64x2_t].eltype =3D unsigned_intDI_type_node; =20 - /* Init poly vector element types with scalar poly types. */ - arm_simd_types[Poly8x8_t].eltype =3D arm_simd_polyQI_type_node; - arm_simd_types[Poly8x16_t].eltype =3D arm_simd_polyQI_type_node; - arm_simd_types[Poly16x4_t].eltype =3D arm_simd_polyHI_type_node; - arm_simd_types[Poly16x8_t].eltype =3D arm_simd_polyHI_type_node; /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default mangling. */ =20 @@ -1006,6 +1010,8 @@ arm_init_simd_builtin_types (void) tree eltype =3D arm_simd_types[i].eltype; machine_mode mode =3D arm_simd_types[i].mode; =20 + if (eltype =3D=3D NULL) + continue; if (arm_simd_types[i].itype =3D=3D NULL) arm_simd_types[i].itype =3D build_distinct_type_copy @@ -1231,15 +1237,6 @@ arm_init_neon_builtins (void) system. */ arm_init_simd_builtin_scalar_types (); =20 - tree lane_check_fpr =3D build_function_type_list (void_type_node, - intSI_type_node, - intSI_type_node, - NULL); - arm_builtin_decls[ARM_BUILTIN_NEON_LANE_CHECK] =3D - add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr, - ARM_BUILTIN_NEON_LANE_CHECK, BUILT_IN_MD, - NULL, NULL_TREE); - for (i =3D 0; i < ARRAY_SIZE (neon_builtin_data); i++, fcode++) { arm_builtin_datum *d =3D &neon_builtin_data[i]; @@ -1956,6 +1953,15 @@ arm_init_builtins (void) =20 if (TARGET_MAYBE_HARD_FLOAT) { + tree lane_check_fpr =3D build_function_type_list (void_type_node, + intSI_type_node, + intSI_type_node, + NULL); + arm_builtin_decls[ARM_BUILTIN_SIMD_LANE_CHECK] + =3D add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr, + ARM_BUILTIN_SIMD_LANE_CHECK, BUILT_IN_MD, + NULL, NULL_TREE); + arm_init_neon_builtins (); arm_init_vfp_builtins (); arm_init_crypto_builtins (); @@ -2201,6 +2207,47 @@ neon_dereference_pointer (tree exp, tree type, machi= ne_mode mem_mode, build_int_cst (build_pointer_type (array_type), 0)); } =20 +/* EXP is a pointer argument to a vector scatter store intrinsics. + + Consider the following example: + VSTRW.
Qd, [Qm{, #+/-}]! + When used as the base register for the target address, + this function is used to derive and return an expression for the + accessed memory. + + The intrinsic function operates on a block of registers that has mode + REG_MODE. This block contains vectors of type TYPE_MODE. The function + references the memory at EXP of type TYPE and in mode MEM_MODE. This + mode may be BLKmode if no more suitable mode is available. */ + +static tree +mve_dereference_pointer (tree exp, tree type, machine_mode reg_mode, + machine_mode vector_mode) +{ + HOST_WIDE_INT reg_size, vector_size, nelems; + tree elem_type, upper_bound, array_type; + + /* Work out the size of each vector in bytes. */ + vector_size =3D GET_MODE_SIZE (vector_mode); + + /* Work out the size of the register block in bytes. */ + reg_size =3D GET_MODE_SIZE (reg_mode); + + /* Work out the type of each element. */ + gcc_assert (POINTER_TYPE_P (type)); + elem_type =3D TREE_TYPE (type); + + nelems =3D reg_size / vector_size; + + /* Create a type that describes the full access. */ + upper_bound =3D build_int_cst (size_type_node, nelems - 1); + array_type =3D build_array_type (elem_type, build_index_type (upper_boun= d)); + + /* Dereference EXP using that type. */ + return fold_build2 (MEM_REF, array_type, exp, + build_int_cst (build_pointer_type (array_type), 0)); +} + /* Expand a builtin. */ static rtx arm_expand_builtin_args (rtx target, machine_mode map_mode, int fcode, @@ -2239,10 +2286,17 @@ arm_expand_builtin_args (rtx target, machine_mode m= ap_mode, int fcode, { machine_mode other_mode =3D insn_data[icode].operand[1 - opno].mode; - arg[argc] =3D neon_dereference_pointer (arg[argc], + if (TARGET_HAVE_MVE && mode[argc] !=3D other_mode) + { + arg[argc] =3D mve_dereference_pointer (arg[argc], TREE_VALUE (formals), - mode[argc], other_mode, - map_mode); + other_mode, map_mode); + } + else + arg[argc] =3D neon_dereference_pointer (arg[argc], + TREE_VALUE (formals), + mode[argc], other_mode, + map_mode); } =20 /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and @@ -2548,22 +2602,6 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx ta= rget) return const0_rtx; } =20 - if (fcode =3D=3D ARM_BUILTIN_NEON_LANE_CHECK) - { - /* Builtin is only to check bounds of the lane passed to some intrin= sics - that are implemented with gcc vector extensions in arm_neon.h. */ - - tree nlanes =3D CALL_EXPR_ARG (exp, 0); - gcc_assert (TREE_CODE (nlanes) =3D=3D INTEGER_CST); - rtx lane_idx =3D expand_normal (CALL_EXPR_ARG (exp, 1)); - if (CONST_INT_P (lane_idx)) - neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp); - else - error ("%Klane index must be a constant immediate", exp); - /* Don't generate any RTL. */ - return const0_rtx; - } - arm_builtin_datum *d =3D &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START]; =20 @@ -2625,6 +2663,22 @@ arm_expand_builtin (tree exp, int mask; int imm; =20 + if (fcode =3D=3D ARM_BUILTIN_SIMD_LANE_CHECK) + { + /* Builtin is only to check bounds of the lane passed to some intrin= sics + that are implemented with gcc vector extensions in arm_neon.h. */ + + tree nlanes =3D CALL_EXPR_ARG (exp, 0); + gcc_assert (TREE_CODE (nlanes) =3D=3D INTEGER_CST); + rtx lane_idx =3D expand_normal (CALL_EXPR_ARG (exp, 1)); + if (CONST_INT_P (lane_idx)) + neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp); + else + error ("%Klane index must be a constant immediate", exp); + /* Don't generate any RTL. */ + return const0_rtx; + } + if (fcode >=3D ARM_BUILTIN_ACLE_BASE) return arm_expand_acle_builtin (fcode, exp, target); =20 diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index 34695fa0112e90e4bdf317da0b9fd1d3194bf0a2..0fe7d371c348818f25901c5d84b= e94589523c9a6 100644 --- a/gcc/config/arm/arm-c.c +++ b/gcc/config/arm/arm-c.c @@ -79,6 +79,16 @@ arm_cpu_builtins (struct cpp_reader* pfile) def_or_undef_macro (pfile, "__ARM_FEATURE_COMPLEX", TARGET_COMPLEX); def_or_undef_macro (pfile, "__ARM_32BIT_STATE", TARGET_32BIT); =20 + cpp_undef (pfile, "__ARM_FEATURE_MVE"); + if (TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT) + { + builtin_define_with_int_value ("__ARM_FEATURE_MVE", 3); + } + else if (TARGET_HAVE_MVE) + { + builtin_define_with_int_value ("__ARM_FEATURE_MVE", 1); + } + cpp_undef (pfile, "__ARM_FEATURE_CMSE"); if (arm_arch8 && !arm_arch_notm) { diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 5b49049cc45c0bccfa9d67eac0940250fc5dd95a..d4612ae4553697989611d772f7b= b0061a04b98b6 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -85,7 +85,7 @@ extern bool ldm_stm_operation_p (rtx, bool, machine_mode = mode, extern bool clear_operation_p (rtx, bool); extern int arm_const_double_rtx (rtx); extern int vfp3_const_double_rtx (rtx); -extern int neon_immediate_valid_for_move (rtx, machine_mode, rtx *, int *); +extern int simd_immediate_valid_for_move (rtx, machine_mode, rtx *, int *); extern int neon_immediate_valid_for_logic (rtx, machine_mode, int, rtx *, int *); extern int neon_immediate_valid_for_shift (rtx, machine_mode, rtx *, diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 8b07c423fb6b071642fccc48424fe244d97dcbc2..c755df420b52798773ee99f54fa= f6689d4a16215 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -751,7 +751,8 @@ extern int arm_arch_cmse; /* s0-s15 VFP scratch (aka d0-d7). s16-s31 S VFP variable (aka d8-d15). vfpcc Not a real register. Represents the VFP condition - code flags. */ + code flags. + vpr Used to represent MVE VPR predication. */ =20 /* The stack backtrace structure is as follows: fp points to here: | save code pointer | [fp] @@ -792,7 +793,7 @@ extern int arm_arch_cmse; 1,1,1,1,1,1,1,1, \ 1,1,1,1, \ /* Specials. */ \ - 1,1,1,1,1,1 \ + 1,1,1,1,1,1,1 \ } =20 /* 1 for registers not available across function calls. @@ -822,7 +823,7 @@ extern int arm_arch_cmse; 1,1,1,1,1,1,1,1, \ 1,1,1,1, \ /* Specials. */ \ - 1,1,1,1,1,1 \ + 1,1,1,1,1,1,1 \ } =20 #ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE @@ -998,10 +999,10 @@ extern int arm_arch_cmse; && (LAST_VFP_REGNUM - (REGNUM) >=3D 2 * (N) - 1)) =20 /* The number of hard registers is 16 ARM + 1 CC + 1 SFP + 1 AFP - + 1 APSRQ + 1 APSRGE. */ + + 1 APSRQ + 1 APSRGE + 1 VPR. */ /* Intel Wireless MMX Technology registers add 16 + 4 more. */ /* VFP (VFP3) adds 32 (64) + 1 VFPCC. */ -#define FIRST_PSEUDO_REGISTER 106 +#define FIRST_PSEUDO_REGISTER 107 =20 #define DBX_REGISTER_NUMBER(REGNO) arm_dbx_register_number (REGNO) =20 @@ -1029,11 +1030,26 @@ extern int arm_arch_cmse; ((MODE) =3D=3D V4SImode || (MODE) =3D=3D V8HImode || (MODE) =3D=3D V16QI= mode \ || (MODE) =3D=3D V8HFmode || (MODE) =3D=3D V4SFmode || (MODE) =3D=3D V2= DImode) =20 +#define VALID_MVE_MODE(MODE) \ + ((MODE) =3D=3D V2DImode ||(MODE) =3D=3D V4SImode || (MODE) =3D=3D V8HImo= de \ + || (MODE) =3D=3D V16QImode || (MODE) =3D=3D V8HFmode || (MODE) =3D=3D V= 4SFmode \ + || (MODE) =3D=3D V2DFmode) + +#define VALID_MVE_SI_MODE(MODE) \ + ((MODE) =3D=3D V2DImode ||(MODE) =3D=3D V4SImode || (MODE) =3D=3D V8HImo= de \ + || (MODE) =3D=3D V16QImode) + +#define VALID_MVE_SF_MODE(MODE) \ + ((MODE) =3D=3D V8HFmode || (MODE) =3D=3D V4SFmode || (MODE) =3D=3D V2DFm= ode) + /* Structure modes valid for Neon registers. */ #define VALID_NEON_STRUCT_MODE(MODE) \ ((MODE) =3D=3D TImode || (MODE) =3D=3D EImode || (MODE) =3D=3D OImode \ || (MODE) =3D=3D CImode || (MODE) =3D=3D XImode) =20 +#define VALID_MVE_STRUCT_MODE(MODE) \ + ((MODE) =3D=3D TImode || (MODE) =3D=3D OImode || (MODE) =3D=3D XImode) + /* The register numbers in sequence, for passing to arm_gen_load_multiple.= */ extern int arm_regs_in_sequence[]; =20 @@ -1085,9 +1101,13 @@ extern int arm_regs_in_sequence[]; /* Registers not for general use. */ \ CC_REGNUM, VFPCC_REGNUM, \ FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, \ - SP_REGNUM, PC_REGNUM, APSRQ_REGNUM, APSRGE_REGNUM \ + SP_REGNUM, PC_REGNUM, APSRQ_REGNUM, APSRGE_REGNUM, \ + VPR_REGNUM \ } =20 +#define IS_VPR_REGNUM(REGNUM) \ + ((REGNUM) =3D=3D VPR_REGNUM) + /* Use different register alloc ordering for Thumb. */ #define ADJUST_REG_ALLOC_ORDER arm_order_regs_for_local_alloc () =20 @@ -1124,6 +1144,7 @@ enum reg_class VFPCC_REG, SFP_REG, AFP_REG, + VPR_REG, ALL_REGS, LIM_REG_CLASSES }; @@ -1131,7 +1152,7 @@ enum reg_class #define N_REG_CLASSES (int) LIM_REG_CLASSES =20 /* Give names of register classes as strings for dump file. */ -#define REG_CLASS_NAMES \ +#define REG_CLASS_NAMES \ { \ "NO_REGS", \ "LO_REGS", \ @@ -1151,6 +1172,7 @@ enum reg_class "VFPCC_REG", \ "SFP_REG", \ "AFP_REG", \ + "VPR_REG", \ "ALL_REGS" \ } =20 @@ -1177,7 +1199,8 @@ enum reg_class { 0x00000000, 0x00000000, 0x00000000, 0x00000020 }, /* VFPCC_REG */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000040 }, /* SFP_REG */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000080 }, /* AFP_REG */ \ - { 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F } /* ALL_REGS */ \ + { 0x00000000, 0x00000000, 0x00000000, 0x00000100 }, /* VPR_REG. */ \ + { 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000010F } /* ALL_REGS. */ \ } =20 #define FP_SYSREGS \ diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 883c2a9179d7e6d69225f8d104228d15702ecef7..6faed76206b93c1a9dea048e2f6= 93dc16ee58072 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3759,7 +3759,8 @@ arm_options_perform_arch_sanity_checks (void) else if (TARGET_HARD_FLOAT_ABI) { arm_pcs_default =3D ARM_PCS_AAPCS_VFP; - if (!bitmap_bit_p (arm_active_target.isa, isa_bit_vfpv2)) + if (!bitmap_bit_p (arm_active_target.isa, isa_bit_vfpv2) + && !bitmap_bit_p (arm_active_target.isa, isa_bit_mve)) error ("%<-mfloat-abi=3Dhard%>: selected processor lacks an FPU"); } else @@ -4230,7 +4231,7 @@ use_return_insn (int iscond, rtx sibling) =20 /* Can't be done if any of the VFP regs are pushed, since this also requires an insn. */ - if (TARGET_HARD_FLOAT) + if (TARGET_HARD_FLOAT || TARGET_HAVE_MVE) for (regno =3D FIRST_VFP_REGNUM; regno <=3D LAST_VFP_REGNUM; regno++) if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) return 0; @@ -6289,7 +6290,7 @@ aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, machine_mo= de mode, { pcum->aapcs_vfp_reg_alloc =3D mask << regno; if (mode =3D=3D BLKmode - || (mode =3D=3D TImode && ! TARGET_NEON) + || (mode =3D=3D TImode && ! (TARGET_NEON || TARGET_HAVE_MVE)) || ! arm_hard_regno_mode_ok (FIRST_VFP_REGNUM + regno, mode)) { int i; @@ -6297,7 +6298,7 @@ aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, machine_mo= de mode, int rshift =3D shift; machine_mode rmode =3D pcum->aapcs_vfp_rmode; rtx par; - if (!TARGET_NEON) + if (!(TARGET_NEON || TARGET_HAVE_MVE)) { /* Avoid using unsupported vector modes. */ if (rmode =3D=3D V2SImode) @@ -6343,7 +6344,7 @@ aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_varia= nt ATTRIBUTE_UNUSED, if (mode =3D=3D BLKmode || (GET_MODE_CLASS (mode) =3D=3D MODE_INT && GET_MODE_SIZE (mode) >=3D GET_MODE_SIZE (TImode) - && !TARGET_NEON)) + && !(TARGET_NEON || TARGET_HAVE_MVE))) { int count; machine_mode ag_mode; @@ -6354,7 +6355,7 @@ aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_varia= nt ATTRIBUTE_UNUSED, aapcs_vfp_is_call_or_return_candidate (pcs_variant, mode, type, &ag_mode, &count); =20 - if (!TARGET_NEON) + if (!(TARGET_NEON || TARGET_HAVE_MVE)) { if (ag_mode =3D=3D V2SImode) ag_mode =3D DImode; @@ -8253,7 +8254,9 @@ thumb2_legitimate_address_p (machine_mode mode, rtx x= , int strict_p) && CONST_INT_P (XEXP (XEXP (x, 0), 1))))) return 1; =20 - else if (mode =3D=3D TImode || (TARGET_NEON && VALID_NEON_STRUCT_MODE (m= ode))) + else if (mode =3D=3D TImode + || (TARGET_NEON && VALID_NEON_STRUCT_MODE (mode)) + || (TARGET_HAVE_MVE && VALID_MVE_STRUCT_MODE (mode))) return 0; =20 else if (code =3D=3D PLUS) @@ -9800,7 +9803,7 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, en= um rtx_code outer_code, /* Assume that most copies can be done with a single insn, unless we don't have HW FP, in which case everything larger than word mode will require two insns. */ - *cost =3D COSTS_N_INSNS (((!TARGET_HARD_FLOAT + *cost =3D COSTS_N_INSNS (((!(TARGET_HARD_FLOAT || TARGET_HAVE_MVE) && GET_MODE_SIZE (mode) > 4) || mode =3D=3D DImode) ? 2 : 1); @@ -11281,10 +11284,10 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code= , enum rtx_code outer_code, =20 case CONST_VECTOR: /* Fixme. */ - if (TARGET_NEON - && TARGET_HARD_FLOAT - && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)) - && neon_immediate_valid_for_move (x, mode, NULL, NULL)) + if (((TARGET_NEON && TARGET_HARD_FLOAT + && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode))) + || TARGET_HAVE_MVE) + && simd_immediate_valid_for_move (x, mode, NULL, NULL)) *cost =3D COSTS_N_INSNS (1); else *cost =3D COSTS_N_INSNS (4); @@ -12328,8 +12331,8 @@ vfp3_const_double_rtx (rtx x) return vfp3_const_double_index (x) !=3D -1; } =20 -/* Recognize immediates which can be used in various Neon instructions. Le= gal - immediates are described by the following table (for VMVN variants, the +/* Recognize immediates which can be used in various Neon and MVE instruct= ions. + Legal immediates are described by the following table (for VMVN variant= s, the bitwise inverse of the constant shown is recognized. In either case, VM= OV is output and the correct instruction to use for a given constant is ch= osen by the assembler). The constant shown is replicated across all elements= of @@ -12380,7 +12383,7 @@ vfp3_const_double_rtx (rtx x) -1 if the given value doesn't match any of the listed patterns. */ static int -neon_valid_immediate (rtx op, machine_mode mode, int inverse, +simd_valid_immediate (rtx op, machine_mode mode, int inverse, rtx *modconst, int *elementwidth) { #define CHECK(STRIDE, ELSIZE, CLASS, TEST) \ @@ -12412,6 +12415,10 @@ neon_valid_immediate (rtx op, machine_mode mode, i= nt inverse, =20 innersize =3D GET_MODE_UNIT_SIZE (mode); =20 + /* Only support 128-bit vectors for MVE. */ + if (TARGET_HAVE_MVE && (!vector || n_elts * innersize !=3D 16)) + return -1; + /* Vectors of float constants. */ if (GET_MODE_CLASS (mode) =3D=3D MODE_VECTOR_FLOAT) { @@ -12560,18 +12567,19 @@ neon_valid_immediate (rtx op, machine_mode mode, = int inverse, #undef CHECK } =20 -/* Return TRUE if rtx X is legal for use as either a Neon VMOV (or, implic= itly, - VMVN) immediate. Write back width per element to *ELEMENTWIDTH (or zero= for - float elements), and a modified constant (whatever should be output for= a - VMOV) in *MODCONST. */ - +/* Return TRUE if rtx X is legal for use as either a Neon or MVE VMOV (or, + implicitly, VMVN) immediate. Write back width per element to *ELEMENTW= IDTH + (or zero for float elements), and a modified constant (whatever should = be + output for a VMOV) in *MODCONST. "neon_immediate_valid_for_move" funct= ion is + modified to "simd_immediate_valid_for_move" as this function will be us= ed + both by neon and mve. */ int -neon_immediate_valid_for_move (rtx op, machine_mode mode, +simd_immediate_valid_for_move (rtx op, machine_mode mode, rtx *modconst, int *elementwidth) { rtx tmpconst; int tmpwidth; - int retval =3D neon_valid_immediate (op, mode, 0, &tmpconst, &tmpwidth); + int retval =3D simd_valid_immediate (op, mode, 0, &tmpconst, &tmpwidth); =20 if (retval =3D=3D -1) return 0; @@ -12588,7 +12596,7 @@ neon_immediate_valid_for_move (rtx op, machine_mode= mode, /* Return TRUE if rtx X is legal for use in a VORR or VBIC instruction. If the immediate is valid, write a constant suitable for using as an opera= nd to VORR/VBIC/VAND/VORN to *MODCONST and the corresponding element width= to - *ELEMENTWIDTH. See neon_valid_immediate for description of INVERSE. */ + *ELEMENTWIDTH. See simd_valid_immediate for description of INVERSE. */ =20 int neon_immediate_valid_for_logic (rtx op, machine_mode mode, int inverse, @@ -12596,7 +12604,7 @@ neon_immediate_valid_for_logic (rtx op, machine_mod= e mode, int inverse, { rtx tmpconst; int tmpwidth; - int retval =3D neon_valid_immediate (op, mode, inverse, &tmpconst, &tmpw= idth); + int retval =3D simd_valid_immediate (op, mode, inverse, &tmpconst, &tmpw= idth); =20 if (retval < 0 || retval > 5) return 0; @@ -12803,7 +12811,7 @@ neon_make_constant (rtx vals) gcc_unreachable (); =20 if (const_vec !=3D NULL - && neon_immediate_valid_for_move (const_vec, mode, NULL, NULL)) + && simd_immediate_valid_for_move (const_vec, mode, NULL, NULL)) /* Load using VMOV. On Cortex-A8 this takes one cycle. */ return const_vec; else if ((target =3D neon_vdup_constant (vals)) !=3D NULL_RTX) @@ -13080,6 +13088,15 @@ neon_vector_mem_operand (rtx op, int type, bool st= rict) && (INTVAL (XEXP (ind, 1)) & 3) =3D=3D 0) return TRUE; =20 + if (type =3D=3D 1 && TARGET_HAVE_MVE + && (GET_CODE (ind) =3D=3D POST_INC || GET_CODE (ind) =3D=3D PRE_DEC)) + { + rtx ind1 =3D XEXP (ind, 0); + if (!REG_P (ind1)) + return 0; + return NEON_REGNO_OK_FOR_QUAD (REGNO (ind1)); + } + return FALSE; } =20 @@ -19936,7 +19953,7 @@ output_move_neon (rtx *operands) { case POST_INC: /* We have to use vldm / vstm for too-large modes. */ - if (nregs > 4) + if (nregs > 4 || (TARGET_HAVE_MVE && nregs >=3D 2)) { templ =3D "v%smia%%?\t%%0!, %%h1"; ops[0] =3D XEXP (addr, 0); @@ -19965,7 +19982,7 @@ output_move_neon (rtx *operands) /* We have to use vldm / vstm for too-large modes. */ if (nregs > 1) { - if (nregs > 4) + if (nregs > 4 || (TARGET_HAVE_MVE && nregs >=3D 2)) templ =3D "v%smia%%?\t%%m0, %%h1"; else templ =3D "v%s1.64\t%%h1, %%A0"; @@ -19980,29 +19997,40 @@ output_move_neon (rtx *operands) { int i; int overlap =3D -1; - for (i =3D 0; i < nregs; i++) + if (TARGET_HAVE_MVE && !BYTES_BIG_ENDIAN) { - /* We're only using DImode here because it's a convenient size. */ - ops[0] =3D gen_rtx_REG (DImode, REGNO (reg) + 2 * i); - ops[1] =3D adjust_address (mem, DImode, 8 * i); - if (reg_overlap_mentioned_p (ops[0], mem)) + sprintf (buff, "v%srw.32\t%%q0, %%1", load ? "ld" : "st"); + ops[0] =3D reg; + ops[1] =3D mem; + output_asm_insn (buff, ops); + } + else + { + for (i =3D 0; i < nregs; i++) { - gcc_assert (overlap =3D=3D -1); - overlap =3D i; + /* We're only using DImode here because it's a convenient + size. */ + ops[0] =3D gen_rtx_REG (DImode, REGNO (reg) + 2 * i); + ops[1] =3D adjust_address (mem, DImode, 8 * i); + if (reg_overlap_mentioned_p (ops[0], mem)) + { + gcc_assert (overlap =3D=3D -1); + overlap =3D i; + } + else + { + sprintf (buff, "v%sr%%?\t%%P0, %%1", load ? "ld" : "st"); + output_asm_insn (buff, ops); + } } - else + if (overlap !=3D -1) { + ops[0] =3D gen_rtx_REG (DImode, REGNO (reg) + 2 * overlap); + ops[1] =3D adjust_address (mem, SImode, 8 * overlap); sprintf (buff, "v%sr%%?\t%%P0, %%1", load ? "ld" : "st"); output_asm_insn (buff, ops); } } - if (overlap !=3D -1) - { - ops[0] =3D gen_rtx_REG (DImode, REGNO (reg) + 2 * overlap); - ops[1] =3D adjust_address (mem, SImode, 8 * overlap); - sprintf (buff, "v%sr%%?\t%%P0, %%1", load ? "ld" : "st"); - output_asm_insn (buff, ops); - } =20 return ""; } @@ -22223,7 +22251,7 @@ arm_compute_frame_layout (void) func_type =3D arm_current_func_type (); /* Space for saved VFP registers. */ if (! IS_VOLATILE (func_type) - && TARGET_HARD_FLOAT) + && (TARGET_HARD_FLOAT || TARGET_HAVE_MVE)) saved +=3D arm_get_vfp_saved_size (); =20 /* Allocate space for saving/restoring FPCXTNS in Armv8.1-M Mainline @@ -22447,7 +22475,7 @@ arm_save_coproc_regs(void) saved_size +=3D 8; } =20 - if (TARGET_HARD_FLOAT) + if (TARGET_HARD_FLOAT || TARGET_HAVE_MVE) { start_reg =3D FIRST_VFP_REGNUM; =20 @@ -23749,6 +23777,53 @@ arm_print_operand (FILE *stream, rtx x, int code) } return; =20 + /* To print the memory operand with "Us" constraint. Based on the rtx= _code + the memory operands output looks like following. + 1. [Rn], #+/- + 2. [Rn, #+/-]! + 3. [Rn]. */ + case 'E': + { + rtx addr; + rtx postinc_reg =3D NULL; + unsigned inc_val =3D 0; + enum rtx_code code; + + gcc_assert (MEM_P (x)); + addr =3D XEXP (x, 0); + code =3D GET_CODE (addr); + if (code =3D=3D POST_INC || code =3D=3D POST_DEC || code =3D=3D PRE_INC + || code =3D=3D PRE_DEC) + { + asm_fprintf (stream, "[%r", REGNO (XEXP (addr, 0))); + inc_val =3D GET_MODE_SIZE (GET_MODE (x)); + if (code =3D=3D POST_INC || code =3D=3D POST_DEC) + asm_fprintf (stream, "], #%s%d",(code =3D=3D POST_INC) + ? "": "-", inc_val); + else + asm_fprintf (stream, ", #%s%d]!",(code =3D=3D PRE_INC) + ? "": "-", inc_val); + } + else if (code =3D=3D POST_MODIFY || code =3D=3D PRE_MODIFY) + { + asm_fprintf (stream, "[%r", REGNO (XEXP (addr, 0))); + postinc_reg =3D XEXP ( XEXP (x, 1), 1); + if (postinc_reg && CONST_INT_P (postinc_reg)) + { + if (code =3D=3D POST_MODIFY) + asm_fprintf (stream, "], #%wd",INTVAL (postinc_reg)); + else + asm_fprintf (stream, ", #%wd]!",INTVAL (postinc_reg)); + } + } + else + { + gcc_assert (REG_P (addr)); + asm_fprintf (stream, "[%r]",REGNO (addr)); + } + } + return; + case 'C': { rtx addr; @@ -23926,9 +24001,10 @@ arm_print_operand_address (FILE *stream, machine_m= ode mode, rtx x) REGNO (XEXP (x, 0)), GET_CODE (x) =3D=3D PRE_DEC ? "-" : "", GET_MODE_SIZE (mode)); + else if (TARGET_HAVE_MVE && (mode =3D=3D OImode || mode =3D=3D XImode)) + asm_fprintf (stream, "[%r]!", REGNO (XEXP (x,0))); else - asm_fprintf (stream, "[%r], #%s%d", - REGNO (XEXP (x, 0)), + asm_fprintf (stream, "[%r], #%s%d", REGNO (XEXP (x, 0)), GET_CODE (x) =3D=3D POST_DEC ? "-" : "", GET_MODE_SIZE (mode)); } @@ -24773,12 +24849,15 @@ arm_hard_regno_mode_ok (unsigned int regno, machi= ne_mode mode) { if (GET_MODE_CLASS (mode) =3D=3D MODE_CC) return (regno =3D=3D CC_REGNUM - || (TARGET_HARD_FLOAT + || ((TARGET_HARD_FLOAT || TARGET_HAVE_MVE) && regno =3D=3D VFPCC_REGNUM)); =20 if (regno =3D=3D CC_REGNUM && GET_MODE_CLASS (mode) !=3D MODE_CC) return false; =20 + if (IS_VPR_REGNUM (regno)) + return true; + if (TARGET_THUMB1) /* For the Thumb we only allow values bigger than SImode in registers 0 - 6, so that there is always a second low @@ -24787,7 +24866,7 @@ arm_hard_regno_mode_ok (unsigned int regno, machine= _mode mode) start of an even numbered register pair. */ return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM); =20 - if (TARGET_HARD_FLOAT && IS_VFP_REGNUM (regno)) + if ((TARGET_HARD_FLOAT || TARGET_HAVE_MVE) && IS_VFP_REGNUM (regno)) { if (mode =3D=3D SFmode || mode =3D=3D SImode) return VFP_REGNO_OK_FOR_SINGLE (regno); @@ -24811,6 +24890,10 @@ arm_hard_regno_mode_ok (unsigned int regno, machin= e_mode mode) || (mode =3D=3D OImode && NEON_REGNO_OK_FOR_NREGS (regno, 4)) || (mode =3D=3D CImode && NEON_REGNO_OK_FOR_NREGS (regno, 6)) || (mode =3D=3D XImode && NEON_REGNO_OK_FOR_NREGS (regno, 8)); + if (TARGET_HAVE_MVE) + return ((VALID_MVE_MODE (mode) && NEON_REGNO_OK_FOR_QUAD (regno)) + || (mode =3D=3D OImode && NEON_REGNO_OK_FOR_NREGS (regno, 4)) + || (mode =3D=3D XImode && NEON_REGNO_OK_FOR_NREGS (regno, 8))); =20 return false; } @@ -24859,13 +24942,18 @@ arm_modes_tieable_p (machine_mode mode1, machine_= mode mode2) /* We specifically want to allow elements of "structure" modes to be tieable to the structure. This more general condition allows other rarer situations too. */ - if (TARGET_NEON - && (VALID_NEON_DREG_MODE (mode1) - || VALID_NEON_QREG_MODE (mode1) - || VALID_NEON_STRUCT_MODE (mode1)) - && (VALID_NEON_DREG_MODE (mode2) - || VALID_NEON_QREG_MODE (mode2) - || VALID_NEON_STRUCT_MODE (mode2))) + if ((TARGET_NEON + && (VALID_NEON_DREG_MODE (mode1) + || VALID_NEON_QREG_MODE (mode1) + || VALID_NEON_STRUCT_MODE (mode1)) + && (VALID_NEON_DREG_MODE (mode2) + || VALID_NEON_QREG_MODE (mode2) + || VALID_NEON_STRUCT_MODE (mode2))) + || (TARGET_HAVE_MVE + && (VALID_MVE_MODE (mode1) + || VALID_MVE_STRUCT_MODE (mode1)) + && (VALID_MVE_MODE (mode2) + || VALID_MVE_STRUCT_MODE (mode2)))) return true; =20 return false; @@ -24880,6 +24968,9 @@ arm_regno_class (int regno) if (regno =3D=3D PC_REGNUM) return NO_REGS; =20 + if (IS_VPR_REGNUM (regno)) + return VPR_REG; + if (TARGET_THUMB1) { if (regno =3D=3D STACK_POINTER_REGNUM) @@ -26731,7 +26822,7 @@ arm_expand_epilogue_apcs_frame (bool really_return) floats_from_frame +=3D 4; } =20 - if (TARGET_HARD_FLOAT) + if (TARGET_HARD_FLOAT || TARGET_HAVE_MVE) { int start_reg; rtx ip_rtx =3D gen_rtx_REG (SImode, IP_REGNUM); @@ -26977,7 +27068,7 @@ arm_expand_epilogue (bool really_return) } } =20 - if (TARGET_HARD_FLOAT) + if (TARGET_HARD_FLOAT || TARGET_HAVE_MVE) { /* Generate VFP register multi-pop. */ int end_reg =3D LAST_VFP_REGNUM + 1; @@ -27148,7 +27239,7 @@ arm_expand_epilogue (bool really_return) GEN_INT (FPCXTNS_ENUM))); RTX_FRAME_RELATED_P (insn) =3D 1; } - } + } =20 if (!really_return) return; @@ -28370,6 +28461,15 @@ arm_vector_mode_supported_p (machine_mode mode) || mode =3D=3D V2HAmode)) return true; =20 + if (TARGET_HAVE_MVE + && (mode =3D=3D V2DImode || mode =3D=3D V4SImode || mode =3D=3D V8HI= mode + || mode =3D=3D V16QImode)) + return true; + + if (TARGET_HAVE_MVE_FLOAT + && (mode =3D=3D V2DFmode || mode =3D=3D V4SFmode || mode =3D=3D V8HF= mode)) + return true; + return false; } =20 @@ -28387,6 +28487,10 @@ arm_array_mode_supported_p (machine_mode mode, && (nelems >=3D 2 && nelems <=3D 4)) return true; =20 + if (TARGET_HAVE_MVE && !BYTES_BIG_ENDIAN + && VALID_MVE_MODE (mode) && (nelems =3D=3D 2 || nelems =3D=3D 4)) + return true; + return false; } =20 @@ -29435,7 +29539,7 @@ arm_conditional_register_usage (void) if (TARGET_THUMB1) fixed_regs[LR_REGNUM] =3D call_used_regs[LR_REGNUM] =3D 1; =20 - if (TARGET_32BIT && TARGET_HARD_FLOAT) + if (TARGET_32BIT && (TARGET_HARD_FLOAT || TARGET_HAVE_MVE)) { /* VFPv3 registers are disabled when earlier VFP versions are selected due to the definition of @@ -29447,6 +29551,8 @@ arm_conditional_register_usage (void) call_used_regs[regno] =3D regno < FIRST_VFP_REGNUM + 16 || regno >=3D FIRST_VFP_REGNUM + 32; } + if (TARGET_HAVE_MVE) + fixed_regs[VPR_REGNUM] =3D 0; } =20 if (TARGET_REALLY_IWMMXT && !TARGET_GENERAL_REGS_ONLY) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index c62ad1b360ebecd5368e90ea5634488eef22f2fc..689baa0b0ff63ef90f47d2fd844= cb98c9a1457a0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -41,6 +41,7 @@ (VFPCC_REGNUM 101) ; VFP Condition code pseudo register (APSRQ_REGNUM 104) ; Q bit pseudo register (APSRGE_REGNUM 105) ; GE bits pseudo register + (VPR_REGNUM 106) ; Vector Predication Register - MVE register. ] ) ;; 3rd operand to select_dominance_cc_mode @@ -7293,7 +7294,7 @@ [(set (match_operand:SF 0 "nonimmediate_operand" "=3Dr,r,m") (match_operand:SF 1 "general_operand" "r,mE,r"))] "TARGET_32BIT - && TARGET_SOFT_FLOAT + && TARGET_SOFT_FLOAT && !TARGET_HAVE_MVE && (!MEM_P (operands[0]) || register_operand (operands[1], SFmode))" { @@ -7416,8 +7417,8 @@ =20 (define_insn "*movdf_soft_insn" [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=3Dr,r,r,r,m") - (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))] - "TARGET_32BIT && TARGET_SOFT_FLOAT + (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))] + "TARGET_32BIT && TARGET_SOFT_FLOAT && !TARGET_HAVE_MVE && ( register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" "* @@ -11681,7 +11682,7 @@ (match_operand:SI 2 "const_int_I_operand" "I"))) (set (match_operand:DF 3 "vfp_hard_register_operand" "") (mem:DF (match_dup 1)))])] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && (TARGET_HARD_FLOAT || TARGET_HAVE_MVE)" "* { int num_regs =3D XVECLEN (operands[0], 0); @@ -12624,7 +12625,7 @@ (set_attr "length" "8")] ) =20 -;; Vector bits common to IWMMXT and Neon +;; Vector bits common to IWMMXT, Neon and MVE (include "vec-common.md") ;; Load the Intel Wireless Multimedia Extension patterns (include "iwmmxt.md") @@ -12642,3 +12643,5 @@ (include "sync.md") ;; Fixed-point patterns (include "arm-fixed.md") +;; M-profile Vector Extensions +(include "mve.md") diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h new file mode 100644 index 0000000000000000000000000000000000000000..5ffb466596b5d8fc330616a6fcc= 7ee37d3e28def --- /dev/null +++ b/gcc/config/arm/arm_mve.h @@ -0,0 +1,59 @@ +/* Arm MVE intrinsics include file. + + Copyright (C) 2019 Free Software Foundation, Inc. + Contributed by Arm. + + 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_ARM_MVE_H +#define _GCC_ARM_MVE_H + +#if !__ARM_FEATURE_MVE +#error "MVE feature not supported" +#endif + +#include +#ifndef __cplusplus +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if (__ARM_FEATURE_MVE & 2) /* MVE Floating point. */ +typedef __fp16 float16_t; +typedef float float32_t; +typedef __simd128_float16_t float16x8_t; +typedef __simd128_float32_t float32x4_t; +#endif + +typedef uint16_t mve_pred16_t; +typedef __simd128_uint8_t uint8x16_t; +typedef __simd128_uint16_t uint16x8_t; +typedef __simd128_uint32_t uint32x4_t; +typedef __simd128_uint64_t uint64x2_t; +typedef __simd128_int8_t int8x16_t; +typedef __simd128_int16_t int16x8_t; +typedef __simd128_int32_t int32x4_t; +typedef __simd128_int64_t int64x2_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _GCC_ARM_MVE_H. */ diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index 6f309b95cc1874ac7bc69e435781070e0c9cb70a..f77084a0efd489491372bb1dafb= c0cd585f0f518 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -44,6 +44,8 @@ ;; in Thumb state: Uu, Uw ;; in all states: Q =20 +(define_register_constraint "Up" "TARGET_HAVE_MVE ? VPR_REG : NO_REGS" + "MVE VPR register") =20 (define_register_constraint "t" "TARGET_32BIT ? VFP_LO_REGS : NO_REGS" "The VFP registers @code{s0}-@code{s31}.") diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index c412851843f4468c2c18bce264288705e076ac50..e30325bc1652d378be2544fa322= 69c5c4294d7e9 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -62,6 +62,12 @@ ;; Integer and float modes supported by Neon and IWMMXT. (define_mode_iterator VALL [V2DI V2SI V4HI V8QI V2SF V4SI V8HI V16QI V4SF]) =20 +;; Integer and float modes supported by Neon, IWMMXT and MVE. +(define_mode_iterator VNIM1 [V16QI V8HI V4SI V4SF V2DI]) + +;; Integer and float modes supported by Neon and IWMMXT but not MVE. +(define_mode_iterator VNINOTM1 [V2SI V4HI V8QI V2SF]) + ;; Integer and float modes supported by Neon and IWMMXT, except V2DI. (define_mode_iterator VALLW [V2SI V4HI V8QI V2SF V4SI V8HI V16QI V4SF]) =20 @@ -105,7 +111,8 @@ (define_mode_iterator VQXMOV [V16QI V8HI V8HF V4SI V4SF V2DI TI]) =20 ;; Opaque structure types wider than TImode. -(define_mode_iterator VSTRUCT [EI OI CI XI]) +(define_mode_iterator VSTRUCT [(EI "!TARGET_HAVE_MVE") OI + (CI "!TARGET_HAVE_MVE") XI]) =20 ;; Opaque structure types used in table lookups (except vtbl1/vtbx1). (define_mode_iterator VTAB [TI EI OI]) diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md new file mode 100644 index 0000000000000000000000000000000000000000..53334c6d329dedd482615b99623= 2e85ded7a34f8 --- /dev/null +++ b/gcc/config/arm/mve.md @@ -0,0 +1,78 @@ +;; Arm M-profile Vector Extension Machine Description +;; 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 +;; . + +(define_mode_iterator MVE_types [V16QI V8HI V4SI V2DI TI V8HF V4SF V2DF]) +(define_mode_attr V_sz_elem2 [(V16QI "s8") (V8HI "u16") (V4SI "u32") + (V2DI "u64")]) + +(define_insn "*mve_mov" + [(set (match_operand:MVE_types 0 "s_register_operand" "=3Dw,w,r,w,w,r,w") + (match_operand:MVE_types 1 "general_operand" "w,r,w,Dn,Usi,r,Dm"))] + "TARGET_HAVE_MVE || TARGET_HAVE_MVE_FLOAT" +{ + if (which_alternative =3D=3D 3 || which_alternative =3D=3D 6) + { + int width, is_valid; + static char templ[40]; + + is_valid =3D simd_immediate_valid_for_move (operands[1], mode, + &operands[1], &width); + + gcc_assert (is_valid !=3D 0); + + if (width =3D=3D 0) + return "vmov.f32\t%q0, %1 @ "; + else + sprintf (templ, "vmov.i%d\t%%q0, %%x1 @ ", width); + return templ; + } + switch (which_alternative) + { + case 0: + return "vmov\t%q0, %q1"; + case 1: + return "vmov\t%e0, %Q1, %R1 @ \;vmov\t%f0, %J1, %K1"; + case 2: + return "vmov\t%Q0, %R0, %e1 @ \;vmov\t%J0, %K0, %f1"; + case 4: + if ((TARGET_HAVE_MVE_FLOAT && VALID_MVE_SF_MODE (mode)) + || (MEM_P (operands[1]) + && GET_CODE (XEXP (operands[1], 0)) =3D=3D LABEL_REF)) + return output_move_neon (operands); + else + return "vldrb. %q0, %E1"; + case 5: + return output_move_neon (operands); + case 6: + default: + gcc_unreachable (); + return ""; + } +} + [(set_attr "type" "mve_move,mve_move,mve_move,mve_move,mve_load,mve_move= ,mve_move") + (set_attr "length" "4,8,8,4,8,8,4") + (set_attr "thumb2_pool_range" "*,*,*,*,1018,*,*") + (set_attr "neg_pool_range" "*,*,*,*,996,*,*")]) + +(define_insn "*mve_vstr" + [(set (match_operand:MVE_types 0 "memory_operand" "=3DUs") + (match_operand:MVE_types 1 "s_register_operand" "w"))] + "TARGET_HAVE_MVE" + "vstrb. %q1, %E0" + [(set_attr "type" "mve_store")]) diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 6a0ee28efc9aa9f1fba7b5ae031564f40aa095fe..c23783e0ed914ec21a92828388a= da58ada3c6132 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -35,9 +35,9 @@ =20 (define_insn "*neon_mov" [(set (match_operand:VDX 0 "nonimmediate_operand" - "=3Dw,Un,w, w, w, ?r,?w,?r, ?Us,*r") + "=3Dw,Un,w, w, w, ?r,?w,?r, ?Us,*r") (match_operand:VDX 1 "general_operand" - " w,w, Dm,Dn,Uni, w, r, Usi,r,*r"))] + " w,w, Dm,Dn,Uni, w, r, Usi,r,*r"))] "TARGET_NEON && (register_operand (operands[0], mode) || register_operand (operands[1], mode))" @@ -47,7 +47,7 @@ int width, is_valid; static char templ[40]; =20 - is_valid =3D neon_immediate_valid_for_move (operands[1], mode, + is_valid =3D simd_immediate_valid_for_move (operands[1], mode, &operands[1], &width); =20 gcc_assert (is_valid !=3D 0); @@ -94,7 +94,7 @@ int width, is_valid; static char templ[40]; =20 - is_valid =3D neon_immediate_valid_for_move (operands[1], mode, + is_valid =3D simd_immediate_valid_for_move (operands[1], mode, &operands[1], &width); =20 gcc_assert (is_valid !=3D 0); @@ -147,9 +147,9 @@ }) =20 (define_expand "mov" - [(set (match_operand:VSTRUCT 0 "nonimmediate_operand") - (match_operand:VSTRUCT 1 "general_operand"))] - "TARGET_NEON" + [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "") + (match_operand:VSTRUCT 1 "general_operand" ""))] + "TARGET_NEON || TARGET_HAVE_MVE" { gcc_checking_assert (aligned_operand (operands[0], mode)); gcc_checking_assert (aligned_operand (operands[1], mode)); @@ -160,24 +160,28 @@ } }) =20 -(define_expand "mov" - [(set (match_operand:VH 0 "s_register_operand") - (match_operand:VH 1 "s_register_operand"))] +;; The pattern mov where mode is v4hf and v8hf is split into +;; movv4hf and movv8hf. The pattern movv8hf is common for MVE and +;; NEON, so it is moved into vec-common.md file. +(define_expand "movv4hf" + [(set (match_operand:V4HF 0 "s_register_operand") + (match_operand:V4HF 1 "s_register_operand"))] "TARGET_NEON" { - gcc_checking_assert (aligned_operand (operands[0], mode)); - gcc_checking_assert (aligned_operand (operands[1], mode)); + gcc_checking_assert (aligned_operand (operands[0], E_V4HFmode)); + gcc_checking_assert (aligned_operand (operands[1], E_V4HFmode)); if (can_create_pseudo_p ()) { if (!REG_P (operands[0])) - operands[1] =3D force_reg (mode, operands[1]); + operands[1] =3D force_reg (E_V4HFmode, operands[1]); } }) =20 + (define_insn "*neon_mov" [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=3Dw,Ut,w") (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))] - "TARGET_NEON + "(TARGET_NEON || TARGET_HAVE_MVE) && (register_operand (operands[0], mode) || register_operand (operands[1], mode))" { @@ -213,7 +217,7 @@ (define_split [(set (match_operand:OI 0 "s_register_operand" "") (match_operand:OI 1 "s_register_operand" ""))] - "TARGET_NEON && reload_completed" + "(TARGET_NEON || TARGET_HAVE_MVE) && reload_completed" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (match_dup 3))] { @@ -254,7 +258,7 @@ (define_split [(set (match_operand:XI 0 "s_register_operand" "") (match_operand:XI 1 "s_register_operand" ""))] - "TARGET_NEON && reload_completed" + "(TARGET_NEON || TARGET_HAVE_MVE) && reload_completed" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5)) @@ -489,7 +493,7 @@ (define_expand "vec_init" [(match_operand:VDQ 0 "s_register_operand") (match_operand 1 "" "")] - "TARGET_NEON" + "TARGET_NEON || TARGET_HAVE_MVE" { neon_expand_vector_init (operands[0], operands[1]); DONE; diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 2f0f532edf40d475e4199aa41bd7803fac8d6143..9d74165fe065b03c77918fe9e46= 11967799535f1 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -48,6 +48,16 @@ return guard_addr_operand (XEXP (op, 0), mode); }) =20 +(define_predicate "vpr_register_operand" + (match_code "reg,subreg") +{ + if (GET_CODE (op) =3D=3D SUBREG) + op =3D SUBREG_REG (op); + return REG_P (op) + && (REGNO (op) >=3D FIRST_PSEUDO_REGISTER + || IS_VPR_REGNUM (REGNO (op))); +}) + (define_predicate "imm_for_neon_inv_logic_operand" (match_code "const_vector") { @@ -706,7 +716,7 @@ (define_predicate "imm_for_neon_mov_operand" (match_code "const_vector,const_int") { - return neon_immediate_valid_for_move (op, mode, NULL, NULL); + return simd_immediate_valid_for_move (op, mode, NULL, NULL); }) =20 (define_predicate "imm_for_neon_lshift_operand" diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm index af60c8fc285bb536afeb9ec5c21771a4379755fc..fda5e84355b56a20eb9a22919ab= 1c786120cc8f1 100644 --- a/gcc/config/arm/t-arm +++ b/gcc/config/arm/t-arm @@ -55,6 +55,7 @@ MD_INCLUDES=3D $(srcdir)/config/arm/arm1020e.md \ $(srcdir)/config/arm/ldmstm.md \ $(srcdir)/config/arm/ldrdstrd.md \ $(srcdir)/config/arm/marvell-f-iwmmxt.md \ + $(srcdir)/config/arm/mve.md \ $(srcdir)/config/arm/neon.md \ $(srcdir)/config/arm/predicates.md \ $(srcdir)/config/arm/sync.md \ diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md index 60faad6597935607ed3c5593f941a04bbc924252..c99b846ab387bac633be8b1631f= 0e40b3c827850 100644 --- a/gcc/config/arm/types.md +++ b/gcc/config/arm/types.md @@ -550,6 +550,11 @@ ; The classification below is for TME instructions ; ; tme +; The classification below is for M-profile Vector Extension instructions +; +; mve_move +; mve_store +; mve_load =20 (define_attr "type" "adc_imm,\ @@ -1096,7 +1101,11 @@ crypto_sm3,\ crypto_sm4,\ coproc,\ - tme" + tme,\ +\ + mve_move,\ + mve_store,\ + mve_load" (const_string "untyped")) =20 ; Is this an (integer side) multiply with a 32-bit (or smaller) result? diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md index 33ff5627284d7cc898074b562179938982ecc420..5f5c113cf95afafbb733e1bfd2a= 7c7b8a55651a2 100644 --- a/gcc/config/arm/vec-common.md +++ b/gcc/config/arm/vec-common.md @@ -21,8 +21,31 @@ ;; Vector Moves =20 (define_expand "mov" - [(set (match_operand:VALL 0 "nonimmediate_operand") - (match_operand:VALL 1 "general_operand"))] + [(set (match_operand:VNIM1 0 "nonimmediate_operand") + (match_operand:VNIM1 1 "general_operand"))] + "TARGET_NEON + || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode)) + || (TARGET_HAVE_MVE && VALID_MVE_SI_MODE (mode)) + || (TARGET_HAVE_MVE_FLOAT && VALID_MVE_SF_MODE (mode))" + { + gcc_checking_assert (aligned_operand (operands[0], mode)); + gcc_checking_assert (aligned_operand (operands[1], mode)); + if (can_create_pseudo_p ()) + { + if (!REG_P (operands[0])) + operands[1] =3D force_reg (mode, operands[1]); + else if ((TARGET_NEON || TARGET_HAVE_MVE || TARGET_HAVE_MVE_FLOAT) + && (CONSTANT_P (operands[1]))) + { + operands[1] =3D neon_make_constant (operands[1]); + gcc_assert (operands[1] !=3D NULL_RTX); + } + } +}) + +(define_expand "mov" + [(set (match_operand:VNINOTM1 0 "nonimmediate_operand") + (match_operand:VNINOTM1 1 "general_operand"))] "TARGET_NEON || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))" { @@ -40,6 +63,20 @@ } }) =20 +(define_expand "movv8hf" + [(set (match_operand:V8HF 0 "s_register_operand") + (match_operand:V8HF 1 "s_register_operand"))] + "TARGET_NEON || TARGET_HAVE_MVE_FLOAT" +{ + gcc_checking_assert (aligned_operand (operands[0], E_V8HFmode)); + gcc_checking_assert (aligned_operand (operands[1], E_V8HFmode)); + if (can_create_pseudo_p ()) + { + if (!REG_P (operands[0])) + operands[1] =3D force_reg (E_V8HFmode, operands[1]); + } +}) + ;; Vector arithmetic. Expanders are blank, then unnamed insns implement ;; patterns separately for IWMMXT and Neon. =20 diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index 573db164f01b4ac9ee4a9ee7414872fb93c9e2ca..6349c0570540ec25a599166f5d4= 27fcbdbf2af68 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -311,7 +311,7 @@ && ( register_operand (operands[0], DImode) || register_operand (operands[1], DImode)) && !(TARGET_NEON && CONST_INT_P (operands[1]) - && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL)= )" + && simd_immediate_valid_for_move (operands[1], DImode, NULL, NULL))" "* switch (which_alternative) { diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float.c= b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float.c new file mode 100644 index 0000000000000000000000000000000000000000..c3f81546c9f14f2491c6fb13417= 0f17bcba16069 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve.fp -mfloat-abi=3Dh= ard" } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +float32x4_t +foo32 (float32x4_t value) +{ + float32x4_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldmia.*" } } */ + +float16x8_t +foo16 (float16x8_t value) +{ + float16x8_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldmia.*" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float1.= c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float1.c new file mode 100644 index 0000000000000000000000000000000000000000..ebee0d2f1ad03b66d044d93bf90= 1e0ce78eccba9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve.fp -mfloat-abi=3Dh= ard" } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +float32x4_t value; + +float32x4_t +foo32 () +{ + float32x4_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldmia.*" } } */ + +float16x8_t value1; + +float16x8_t +foo16 () +{ + float16x8_t b =3D value1; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldmia.*" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float2.= c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float2.c new file mode 100644 index 0000000000000000000000000000000000000000..9b9c84d66ef8fd585a42be1ac75= 85d8bc6c529bb --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_float2.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve.fp -mfloat-abi=3Dh= ard" } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +float32x4_t +foo32 () +{ + float32x4_t b =3D {10.0, 12.0, 14.0, 16.0}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32*" } } */ + +float16x8_t +foo16 () +{ + float16x8_t b =3D {32.01}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int.c b= /gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int.c new file mode 100644 index 0000000000000000000000000000000000000000..6b54c3c61f32cf8e0af30272df6= 3f261def0b8c5 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve -mfloat-abi=3Dhard= " } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +int8x16_t +foo8 (int8x16_t value) +{ + int8x16_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.s8*" } } */ + +int16x8_t +foo16 (int16x8_t value) +{ + int16x8_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u16*" } } */ + +int32x4_t +foo32 (int32x4_t value) +{ + int32x4_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u32*" } } */ + +int64x2_t +foo64 (int64x2_t value) +{ + int64x2_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u64*" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int1.c = b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int1.c new file mode 100644 index 0000000000000000000000000000000000000000..748ddecbd4011bb24058c27cd6a= 09d66f71ce581 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int1.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve -mfloat-abi=3Dhard= " } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +int8x16_t value1; +int16x8_t value2; +int32x4_t value3; +int64x2_t value4; + +int8x16_t +foo8 () +{ + int8x16_t b =3D value1; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u8*" } } */ + +int16x8_t +foo16 () +{ + int16x8_t b =3D value2; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u16*" } } */ + +int32x4_t +foo32 () +{ + int32x4_t b =3D value3; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u32" } } */ + +int64x2_t +foo64 () +{ + int64x2_t b =3D value4; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u64" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int2.c = b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int2.c new file mode 100644 index 0000000000000000000000000000000000000000..376ec9ee7fc04ddde98719d2605= 319a378f9a6bb --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_int2.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve -mfloat-abi=3Dhard= " } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +int8x16_t +foo8 () +{ + int8x16_t b =3D {1, 2, 3, 4}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ + +int16x8_t +foo16 (int16x8_t value) +{ + int16x8_t b =3D {1, 2, 3}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ + +int32x4_t +foo32 (int32x4_t value) +{ + int32x4_t b =3D {1, 2}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ + +int64x2_t +foo64 (int64x2_t value) +{ + int64x2_t b =3D {1}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint.c = b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint.c new file mode 100644 index 0000000000000000000000000000000000000000..f001d14f9ca4c851ed4b3371ae9= 599d23d2b62ce --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve -mfloat-abi=3Dhard= " } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +uint8x16_t +foo8 (uint8x16_t value) +{ + uint8x16_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.s8*" } } */ + +uint16x8_t +foo16 (uint16x8_t value) +{ + uint16x8_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u16*" } } */ + +uint32x4_t +foo32 (uint32x4_t value) +{ + uint32x4_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u32*" } } */ + +uint64x2_t +foo64 (uint64x2_t value) +{ + uint64x2_t b =3D value; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u64*" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint1.c= b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint1.c new file mode 100644 index 0000000000000000000000000000000000000000..56d40668d63ba0b24c08944981c= 415054494c37d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint1.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve -mfloat-abi=3Dhard= " } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +uint8x16_t value1; +uint16x8_t value2; +uint32x4_t value3; +uint64x2_t value4; + +uint8x16_t +foo8 () +{ + uint8x16_t b =3D value1; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.s8*" } } */ + +uint16x8_t +foo16 () +{ + uint16x8_t b =3D value2; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u16*" } } */ + +uint32x4_t +foo32 () +{ + uint32x4_t b =3D value3; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u32*" } } */ + +uint64x2_t +foo64 () +{ + uint64x2_t b =3D value4; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrb.u64*" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint2.c= b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint2.c new file mode 100644 index 0000000000000000000000000000000000000000..9ff9b67993ac83cf398880cb655= 10604a37de6a4 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vector_uint2.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=3Darmv8.1-m.main+mve -mfloat-abi=3Dhard= " } */ +/* { dg-skip-if "Skip if not auto" {*-*-*} {"-mfpu=3D*"} {"-mcpu=3Dauto"} = } */ + +#include "arm_mve.h" + +uint8x16_t +foo8 (uint8x16_t value) +{ + uint8x16_t b =3D {1, 2, 3, 4}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ + +uint16x8_t +foo16 (uint16x8_t value) +{ + uint16x8_t b =3D {1, 2, 3}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ + +uint32x4_t +foo32 (uint32x4_t value) +{ + uint32x4_t b =3D {1, 2}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ + +uint64x2_t +foo64 (uint64x2_t value) +{ + uint64x2_t b =3D {1}; + return b; +} + +/* { dg-final { scan-assembler "vmov\\tq\[0-7\], q\[0-7\]" } } */ +/* { dg-final { scan-assembler "vstrb.*" } } */ +/* { dg-final { scan-assembler "vldrw.32.*" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/mve.exp b/gcc/testsuite/gcc.t= arget/arm/mve/mve.exp new file mode 100644 index 0000000000000000000000000000000000000000..77ae3fa292b2892fb22c2f89223= ca19dc16ccc99 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/mve.exp @@ -0,0 +1,47 @@ +# 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an ARM target. +if ![istarget arm*-*-*] 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" +} + +# This variable should only apply to tests called in this exp file. +global dg_runtest_extra_prunes +set dg_runtest_extra_prunes "" +lappend dg_runtest_extra_prunes "warning: switch -m(cpu|arch)=3D.* conflic= ts with -m(cpu|arch)=3D.* switch" + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/intrinsics/*.\[cCS\]]]= \ + "" $DEFAULT_CFLAGS + +# All done. +set dg_runtest_extra_prunes "" +dg-finish --_002_DBBPR08MB4775F9F4A174B7BFD2021C9C9B710DBBPR08MB4775eurp_ Content-Type: application/gzip; name="diff00.patch.gz" Content-Description: diff00.patch.gz Content-Disposition: attachment; filename="diff00.patch.gz"; size=16528; creation-date="Thu, 14 Nov 2019 19:12:54 GMT"; modification-date="Thu, 14 Nov 2019 19:12:54 GMT" Content-ID: <2353866E1B39C04A8CEA79D8D649CF92@eurprd08.prod.outlook.com> Content-Transfer-Encoding: base64 Content-length: 22408 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 zc3N/wsxAOIr3AIBAA== --_002_DBBPR08MB4775F9F4A174B7BFD2021C9C9B710DBBPR08MB4775eurp_--