From patchwork Mon Sep 18 21:26:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Machado X-Patchwork-Id: 76334 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 30A9D38555B9 for ; Mon, 18 Sep 2023 21:32:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 30A9D38555B9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1695072743; bh=8AeRCBEkfawlx/0Tj/9VhXoLqadhQSxOEJVUcT/8ZM8=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=jX1PjVEXL9annWPTgrB/hjmK49dqU/PORaPEij5byQAzQWvR1iLrhDLqezcIqafms A3+dCCrnUxcPfIYb9Ecigu9Kd3Sk9sHEBUil9u+b8iX/dee4joJF/WiBTFjgQjGZHw 8LHpxIGm57gz1uZZsxiuBqDRWJDW1cN6Rt4ji2vM= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on2071.outbound.protection.outlook.com [40.107.13.71]) by sourceware.org (Postfix) with ESMTPS id 810BC385703F for ; Mon, 18 Sep 2023 21:27:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 810BC385703F Received: from FR3P281CA0179.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:a0::16) by PAXPR08MB6494.eurprd08.prod.outlook.com (2603:10a6:102:154::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6792.26; Mon, 18 Sep 2023 21:27:25 +0000 Received: from VI1EUR03FT033.eop-EUR03.prod.protection.outlook.com (2603:10a6:d10:a0:cafe::9e) by FR3P281CA0179.outlook.office365.com (2603:10a6:d10:a0::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6792.26 via Frontend Transport; Mon, 18 Sep 2023 21:27:25 +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 VI1EUR03FT033.mail.protection.outlook.com (100.127.144.234) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.16 via Frontend Transport; Mon, 18 Sep 2023 21:27:24 +0000 Received: ("Tessian outbound 5c548696a0e7:v175"); Mon, 18 Sep 2023 21:27:23 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: f159a735e91404b2 X-CR-MTA-TID: 64aa7808 Received: from 327a7d3fca3d.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 2C557F52-A0B3-4442-8EEA-63E3BC17780E.1; Mon, 18 Sep 2023 21:27:17 +0000 Received: from EUR04-DB3-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 327a7d3fca3d.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Mon, 18 Sep 2023 21:27:17 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lSyGoqpRth6IINuWN/smNh+wQXDc7ZUaRBi98W6ohnqfL21QIB+G5Ce1DmmQXuFgyJ8pIfL3Is2LwmO79YZNC5MTdpbXKPIEUf2cAf5TEAU5HE8SJ1afMjpkgO10GjorMZUfZOVOL47mk/NTYXQiWmn3/zC18Vu3nJh7nprpY7bKM4n7cTA20BTayoKLU6cxx0yjY7t9OgaGOGdCRF6VlWe0NDGLLXqsjiybOzkpnM0xDvtFCNRf/d+fIuYGfOJHQqXFcknMNhDagx6VnP85uHi7NAzlLf6xF4vdd88PXnU6bu2yJ5NoV/d3LHMjLal+eKf4BHTBhmG1PAwonfv7jA== 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=8AeRCBEkfawlx/0Tj/9VhXoLqadhQSxOEJVUcT/8ZM8=; b=n9KIdijx4R5W128KEZX2Xwq1uAI469qgMyOkJXpO4IkYocysAJFhBrd6Bv9fSS/F7Sro8oxNv/zXv/AsD3YXnwSE3Nw4QqMKEd9BX46c2OL5qucnhZ/dZjdwortJTZxfksqQccgYx1VE/7tdCQg2OGv75pLNObhswRW6Ms/trnGpAkrbVJBojkCv1ALtcUFfEshfcW7xUWjcWzFibVmCYJVzTFIH6AhhRZizg2vXpWjHzrJcVcJjAJJ9LOWYj/9C17up9LKDLHJTQ82eJvoZELyhwwDM2mS62u5/lrlaq7LBcHVW/vGlw71/cdfPuBlnjK4fV6J+RbRrhnLwPPxoVw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 40.67.248.234) smtp.rcpttodomain=sourceware.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none Received: from AM6P193CA0133.EURP193.PROD.OUTLOOK.COM (2603:10a6:209:85::38) by DB5PR08MB10285.eurprd08.prod.outlook.com (2603:10a6:10:4a9::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6768.30; Mon, 18 Sep 2023 21:27:09 +0000 Received: from AM7EUR03FT009.eop-EUR03.prod.protection.outlook.com (2603:10a6:209:85:cafe::49) by AM6P193CA0133.outlook.office365.com (2603:10a6:209:85::38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6792.27 via Frontend Transport; Mon, 18 Sep 2023 21:27:09 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 40.67.248.234 as permitted sender) receiver=protection.outlook.com; client-ip=40.67.248.234; helo=nebula.arm.com; pr=C Received: from nebula.arm.com (40.67.248.234) by AM7EUR03FT009.mail.protection.outlook.com (100.127.140.130) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6813.16 via Frontend Transport; Mon, 18 Sep 2023 21:27:09 +0000 Received: from AZ-NEU-EX04.Arm.com (10.251.24.32) by AZ-NEU-EX04.Arm.com (10.251.24.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 18 Sep 2023 21:27:08 +0000 Received: from e129171.arm.com (10.57.64.238) by mail.arm.com (10.251.24.32) with Microsoft SMTP Server id 15.1.2507.27 via Frontend Transport; Mon, 18 Sep 2023 21:27:08 +0000 To: Subject: [PATCH v7 17/18] [gdb/testsuite] sme: Add SVE/SME testcases Date: Mon, 18 Sep 2023 22:26:50 +0100 Message-ID: <20230918212651.660141-18-luis.machado@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230918212651.660141-1-luis.machado@arm.com> References: <20230918212651.660141-1-luis.machado@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-TrafficTypeDiagnostic: AM7EUR03FT009:EE_|DB5PR08MB10285:EE_|VI1EUR03FT033:EE_|PAXPR08MB6494:EE_ X-MS-Office365-Filtering-Correlation-Id: 742c3db8-0639-4769-1285-08dbb88e0cf5 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: iJdwi7NAUA4tCfgMWceXt66xOEZVmV1QFdRUwo3gXTT5Rztmp4C/s44D84P8vFudPPJwFdYBjT+ka302qwgUEY1KSG/ZHDdTZsDI9Q2YHiu4t3QWScCS/8KPgAbPuzOjSXiHl+QSIOsmlly91Kv9M7USkWqPVbd2MRTop3SJm8uTHhlr3tpbSxsN9+l0RPSukfSE3mTFhWEKlnoHu7BrOmt0T3MDHeir3mv5oZFzNxa9Lm0V8Lvn4wWMpAXq+E3lsNzCdupoYI7fQbe8fwxLgI7YZrUllF1c3CoZNs02DRrKscxbYeFFJno26Q33e71FTJe8CgnchlGjFqgGR47EGpTTUWtdjORar/zekNoNOTdncyMv3adD8TSX6mHxnabGZN/Q6QL3uk1avfE2cCGQn8jmgurLAQesUKBimItu7hVg534ypeKOvUhJ8aKu9ql7UtXbEA+k+zQyD/CqY5WzDnf5/nHrn00fEFWkUoMHF2YYVNJTNVlqXBbAqlb56MltQ4bTXVAk3i5tbFeayXjgVAN0D3wXQrsrucs13pQHeHjoDeQissGiAt1jjS1LuGPkxw3KIy6XvRQSgR4q6zwKp5/YxVWy2b8U2r51iPJm2vBTr+3360zuixRkZozkohHIvS3tcc00hGvnWPpvO5dpw5cuQ9t+f9e2hdY8ZgT/ha7FavBJ4RlsFeHXOd490vZSjsJ9H7DIlYqhjdu3DvZamBVrcxO4tFBy4W9ZWn1AGplCA/+eKbC7In/S+Qe+VCID X-Forefront-Antispam-Report-Untrusted: CIP:40.67.248.234; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:nebula.arm.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230031)(4636009)(136003)(39850400004)(376002)(346002)(396003)(186009)(1800799009)(82310400011)(451199024)(46966006)(36840700001)(7696005)(6666004)(47076005)(44832011)(83380400001)(82740400003)(81166007)(86362001)(356005)(36756003)(5660300002)(36860700001)(26005)(1076003)(2616005)(40480700001)(426003)(336012)(2906002)(41300700001)(8676002)(8936002)(4326008)(70586007)(70206006)(54906003)(30864003)(6916009)(316002)(478600001)(2004002)(36900700001)(579004)(559001); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB5PR08MB10285 X-MS-Exchange-Transport-CrossTenantHeadersStripped: VI1EUR03FT033.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: e13d11fb-d3bf-4005-c131-08dbb88e03e0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: bpziWf5u6XxetwROxR/E0IpJuqPgWo2g8iGBRd+C9OS+UqNRsTIjepqC6oEfjze+CDuRJDfoNTHgsnViByYzONifUkTfPUp/wV6ywwrtU1yICr32mtz5BPG0aPFOsoWkexpKsjVeSXQbR6STQa17mlGdQOdS8SOPV4c7in6a0bp0n7LuUqnZogjB5vhe+HPDtDoIk8H/X+KflHvTh+ITaeg9oiqCRMFH+tc9WPQLjpDsqdfsr2XmG5FBC2zPaSF8T2CWfJpbK/zK4uKDNCdckRp5tVpi5mHk0hVErVXhYPzLRVaQ5s4GiPin2to9Pk6G+0LEMStMdjEuDQzkbYE7B5Uil9BFCoY7ox55Mz9ZPq8raHJIQqnkcN8OMVMBJpUUjJYq/aoPQLlDL8YVAxeAbEQ6Q0Xsx94wzTS+1gDxC/PzFcQXcFpPs1LK8LROw7wbO/KKTTsW6nU/IpqbI29dJxodMfN5F+4/F6I+PMtV5bcPRnVQ5/z2G+valKsGkczzm9+G66zU7SaJwJO+bSgBhgcxfQz6bZgsB7ieJzZ0GhlyEqgTQv1SDQmWBdrB4bVmLKiNIUhdTkj+ydkUVW26GnkGvBvVh5CdzKhAOjJgfCFko0AJncgusO29zpVqi0Yg6XajDarCR9qj2OvLn3gAjkGyN194turIlmeOIa6+oIVZ2/W9JFxQF0C83WxdIl3RMQA/voO3BRxTu6wlXOS4SemAsKX5j0n7ozITM0lMa90pJPEmxy8CAAcTwPn0Xo5O 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:(13230031)(4636009)(136003)(39860400002)(396003)(376002)(346002)(1800799009)(451199024)(186009)(82310400011)(40470700004)(46966006)(36840700001)(54906003)(40460700003)(70206006)(70586007)(36860700001)(6916009)(81166007)(316002)(8936002)(8676002)(4326008)(47076005)(82740400003)(41300700001)(7696005)(6666004)(478600001)(83380400001)(107886003)(336012)(1076003)(426003)(2616005)(26005)(86362001)(30864003)(2906002)(44832011)(5660300002)(40480700001)(36756003)(2004002)(579004)(559001); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Sep 2023 21:27:24.3749 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 742c3db8-0639-4769-1285-08dbb88e0cf5 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: VI1EUR03FT033.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR08MB6494 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_NONE, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SCC_5_SHORT_WORD_LINES, SPF_HELO_PASS, SPF_NONE, TXREP, 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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Luis Machado via Gdb-patches From: Luis Machado Reply-To: Luis Machado Cc: thiago.bauermann@linaro.org Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" v7: - Bail out from sme tests if we have a remote target, due to lack of support in the RSP. v3: - Additional documentation for some testcases based on upstream reviews. - Addressed upstream review comments. v2: - Introduced a couple helper functions to determine the available SVE and SME vector lengths. - Before running a batch of tests, validate that the target supports a certain SVE vector length or SME streaming vector length. If not supported, skip that batch of tests. - Fixed up native core file testing to remove generation of a spurious core file, which later would be reported as unexpected by the testsuite. - Fixed tpidr2 dump in core file tests. --- Add 5 SVE/SME tests to exercise all the new features like reading/writing registers, pseudo-registers, signal frames and core files. - Sanity check for SME: Gives a brief smoke test to make sure the most basic of features are working correctly. - ZA unavailability tests: Validates the behavior/content of the ZA register is correct when no payload is available. It also exercises changing the vector lengths. - ZA Availability tests: These tests exercise reading/writing to all the possible ZA pseudo-registers, and validates the state is correct. - Core file tests: Validates that core file reading and writing works correctly and that all state dumped/loaded is sane. This is exercised for both Linux Kernel core files and gcore core files. - Signal frame tests: Validates the correct restoration of SME/SVE/FPSIMD values across signal frames. Since some of these tests are very lengthy and take a little while to run (under QEMU at the moment), I decided to parallelize them into smaller chunks so we can throw some more CPU power at them so they run faster. I'd still like to add a few more tests to give the testsuite more coverage in the areas of SME/SVE. Hopefully in the near future that will happen. Just a reminder that these SME tests are currently unsupported when gdb is connected to a remote target. That's because the RSP doesn't support communicating changes in vector lenghts mid-execution, so gdb will always get wrong state from the remote target. Co-Authored-By: Ezra Sitorus Reviewed-by: Thiago Jung Bauermann --- gdb/testsuite/gdb.arch/aarch64-sme-core-0.exp | 23 ++ gdb/testsuite/gdb.arch/aarch64-sme-core-1.exp | 23 ++ gdb/testsuite/gdb.arch/aarch64-sme-core-2.exp | 23 ++ gdb/testsuite/gdb.arch/aarch64-sme-core-3.exp | 23 ++ gdb/testsuite/gdb.arch/aarch64-sme-core-4.exp | 23 ++ gdb/testsuite/gdb.arch/aarch64-sme-core.c | 372 ++++++++++++++++++ .../gdb.arch/aarch64-sme-core.exp.tcl | 188 +++++++++ .../gdb.arch/aarch64-sme-regs-available-0.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-1.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-2.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-3.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-4.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-5.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-6.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-7.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-8.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available-9.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-available.c | 178 +++++++++ .../aarch64-sme-regs-available.exp.tcl | 245 ++++++++++++ .../gdb.arch/aarch64-sme-regs-sigframe-0.exp | 23 ++ .../gdb.arch/aarch64-sme-regs-sigframe-1.exp | 23 ++ .../gdb.arch/aarch64-sme-regs-sigframe-2.exp | 23 ++ .../gdb.arch/aarch64-sme-regs-sigframe-3.exp | 23 ++ .../gdb.arch/aarch64-sme-regs-sigframe-4.exp | 23 ++ .../gdb.arch/aarch64-sme-regs-sigframe.c | 366 +++++++++++++++++ .../aarch64-sme-regs-sigframe.exp.tcl | 179 +++++++++ .../aarch64-sme-regs-unavailable-0.exp | 26 ++ .../aarch64-sme-regs-unavailable-1.exp | 26 ++ .../aarch64-sme-regs-unavailable-2.exp | 26 ++ .../aarch64-sme-regs-unavailable-3.exp | 26 ++ .../aarch64-sme-regs-unavailable-4.exp | 26 ++ .../aarch64-sme-regs-unavailable-5.exp | 26 ++ .../aarch64-sme-regs-unavailable-6.exp | 26 ++ .../aarch64-sme-regs-unavailable-7.exp | 26 ++ .../aarch64-sme-regs-unavailable-8.exp | 26 ++ .../aarch64-sme-regs-unavailable-9.exp | 26 ++ .../gdb.arch/aarch64-sme-regs-unavailable.c | 152 +++++++ .../aarch64-sme-regs-unavailable.exp.tcl | 212 ++++++++++ gdb/testsuite/gdb.arch/aarch64-sme-sanity.c | 249 ++++++++++++ gdb/testsuite/gdb.arch/aarch64-sme-sanity.exp | 72 ++++ gdb/testsuite/lib/aarch64-scalable.exp | 239 +++++++++++ gdb/testsuite/lib/aarch64-test-sme.c | 90 +++++ gdb/testsuite/lib/aarch64-test-sve.c | 90 +++++ gdb/testsuite/lib/aarch64.exp | 153 +++++++ gdb/testsuite/lib/gdb.exp | 249 ++++++++++++ 45 files changed, 3784 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-core-0.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-core-1.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-core-2.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-core-3.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-core-4.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-core.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-0.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-1.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-2.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-3.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-4.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-5.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-6.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-7.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-8.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available-9.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-available.exp.tcl create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-0.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-1.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-2.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-3.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-4.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.exp.tcl create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-0.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-1.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-2.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-3.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-4.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-5.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-6.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-7.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-8.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-9.exp create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.exp.tcl create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-sanity.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-sme-sanity.exp create mode 100644 gdb/testsuite/lib/aarch64-scalable.exp create mode 100644 gdb/testsuite/lib/aarch64-test-sme.c create mode 100644 gdb/testsuite/lib/aarch64-test-sve.c create mode 100644 gdb/testsuite/lib/aarch64.exp diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-core-0.exp b/gdb/testsuite/gdb.arch/aarch64-sme-core-0.exp new file mode 100644 index 00000000000..5a51bbd8a1d --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-core-0.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: FPSIMD +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (0 ~ 24) out of 125 tests. +set id_start 0 +set id_end 24 +source $srcdir/$subdir/aarch64-sme-core.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-core-1.exp b/gdb/testsuite/gdb.arch/aarch64-sme-core-1.exp new file mode 100644 index 00000000000..41e93b15834 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-core-1.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: SVE +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (25 ~ 49) out of 125 tests. +set id_start 25 +set id_end 49 +source $srcdir/$subdir/aarch64-sme-core.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-core-2.exp b/gdb/testsuite/gdb.arch/aarch64-sme-core-2.exp new file mode 100644 index 00000000000..05144d9f560 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-core-2.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: SSVE +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (50 ~ 74) out of 125 tests. +set id_start 50 +set id_end 74 +source $srcdir/$subdir/aarch64-sme-core.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-core-3.exp b/gdb/testsuite/gdb.arch/aarch64-sme-core-3.exp new file mode 100644 index 00000000000..fa8931a46d1 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-core-3.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: ZA only +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (75 ~ 99) out of 125 tests. +set id_start 75 +set id_end 99 +source $srcdir/$subdir/aarch64-sme-core.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-core-4.exp b/gdb/testsuite/gdb.arch/aarch64-sme-core-4.exp new file mode 100644 index 00000000000..8881898b370 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-core-4.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: ZA + SSVE +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (100 ~ 124) out of 125 tests. +set id_start 100 +set id_end 124 +source $srcdir/$subdir/aarch64-sme-core.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-core.c b/gdb/testsuite/gdb.arch/aarch64-sme-core.c new file mode 100644 index 00000000000..d71d18ebd3b --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-core.c @@ -0,0 +1,372 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 this program. If not, see . */ + +/* Exercise AArch64's Scalable Vector/Matrix Extension core file generation + for GDB. This includes reading Linux Kernel-generated core files and + writing GDB core files via the gcore command and making sure the contents + are sane. */ + +#include +#include +#include +#include +#include +#include + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +#ifndef HWCAP2_SME +#define HWCAP2_SME (1 << 23) +#endif + +#ifndef PR_SVE_SET_VL +#define PR_SVE_SET_VL 50 +#define PR_SVE_GET_VL 51 +#define PR_SVE_VL_LEN_MASK 0xffff +#endif + +#ifndef PR_SME_SET_VL +#define PR_SME_SET_VL 63 +#define PR_SME_GET_VL 64 +#define PR_SME_VL_LEN_MASK 0xffff +#endif + +static void +enable_za () +{ + /* smstart za */ + __asm __volatile (".word 0xD503457F"); +} + +static void +disable_za () +{ + /* smstop za */ + __asm __volatile (".word 0xD503447F"); +} + +static void +enable_sm () +{ + /* smstart sm */ + __asm __volatile (".word 0xD503437F"); +} + +static void +disable_sm () +{ + /* smstop sm */ + __asm __volatile (".word 0xD503427F"); +} + +static void +initialize_fpsimd_state () +{ + char buffer[16]; + + for (int i = 0; i < 16; i++) + buffer[i] = 0x55; + + __asm __volatile ("mov x0, %0\n\t" \ + : : "r" (buffer)); + + __asm __volatile ("ldr q0, [x0]"); + __asm __volatile ("ldr q1, [x0]"); + __asm __volatile ("ldr q2, [x0]"); + __asm __volatile ("ldr q3, [x0]"); + __asm __volatile ("ldr q4, [x0]"); + __asm __volatile ("ldr q5, [x0]"); + __asm __volatile ("ldr q6, [x0]"); + __asm __volatile ("ldr q7, [x0]"); + __asm __volatile ("ldr q8, [x0]"); + __asm __volatile ("ldr q9, [x0]"); + __asm __volatile ("ldr q10, [x0]"); + __asm __volatile ("ldr q11, [x0]"); + __asm __volatile ("ldr q12, [x0]"); + __asm __volatile ("ldr q13, [x0]"); + __asm __volatile ("ldr q14, [x0]"); + __asm __volatile ("ldr q15, [x0]"); + __asm __volatile ("ldr q16, [x0]"); + __asm __volatile ("ldr q17, [x0]"); + __asm __volatile ("ldr q18, [x0]"); + __asm __volatile ("ldr q19, [x0]"); + __asm __volatile ("ldr q20, [x0]"); + __asm __volatile ("ldr q21, [x0]"); + __asm __volatile ("ldr q22, [x0]"); + __asm __volatile ("ldr q23, [x0]"); + __asm __volatile ("ldr q24, [x0]"); + __asm __volatile ("ldr q25, [x0]"); + __asm __volatile ("ldr q26, [x0]"); + __asm __volatile ("ldr q27, [x0]"); + __asm __volatile ("ldr q28, [x0]"); + __asm __volatile ("ldr q29, [x0]"); + __asm __volatile ("ldr q30, [x0]"); + __asm __volatile ("ldr q31, [x0]"); +} + +static void +initialize_za_state () +{ + /* zero za */ + __asm __volatile (".word 0xC00800FF"); + + char buffer[256]; + + for (int i = 0; i < 256; i++) + buffer[i] = 0xaa; + + __asm __volatile ("mov x0, %0\n\t" \ + : : "r" (buffer)); + + /* Initialize loop boundaries. */ + __asm __volatile ("mov w12, 0"); + __asm __volatile ("mov w17, 256"); + + /* loop: ldr za[w12, 0], [x0] */ + __asm __volatile ("loop: .word 0xe1000000"); + __asm __volatile ("add w12, w12, 1"); + __asm __volatile ("cmp w12, w17"); + __asm __volatile ("bne loop"); +} + +static void +initialize_tpidr2 () +{ + __asm __volatile ("mov x0, #0xffffffffffffffff"); + + /* Write x0 to tpidr2. */ + __asm __volatile (".word 0xd51bd0a0"); +} + +static void +initialize_sve_state () +{ + __asm __volatile ("dup z0.b, -1"); + __asm __volatile ("dup z1.b, -1"); + __asm __volatile ("dup z2.b, -1"); + __asm __volatile ("dup z3.b, -1"); + __asm __volatile ("dup z4.b, -1"); + __asm __volatile ("dup z5.b, -1"); + __asm __volatile ("dup z6.b, -1"); + __asm __volatile ("dup z7.b, -1"); + __asm __volatile ("dup z8.b, -1"); + __asm __volatile ("dup z9.b, -1"); + __asm __volatile ("dup z10.b, -1"); + __asm __volatile ("dup z11.b, -1"); + __asm __volatile ("dup z12.b, -1"); + __asm __volatile ("dup z13.b, -1"); + __asm __volatile ("dup z14.b, -1"); + __asm __volatile ("dup z15.b, -1"); + __asm __volatile ("dup z16.b, -1"); + __asm __volatile ("dup z17.b, -1"); + __asm __volatile ("dup z18.b, -1"); + __asm __volatile ("dup z19.b, -1"); + __asm __volatile ("dup z20.b, -1"); + __asm __volatile ("dup z21.b, -1"); + __asm __volatile ("dup z22.b, -1"); + __asm __volatile ("dup z23.b, -1"); + __asm __volatile ("dup z24.b, -1"); + __asm __volatile ("dup z25.b, -1"); + __asm __volatile ("dup z26.b, -1"); + __asm __volatile ("dup z27.b, -1"); + __asm __volatile ("dup z28.b, -1"); + __asm __volatile ("dup z29.b, -1"); + __asm __volatile ("dup z30.b, -1"); + __asm __volatile ("dup z31.b, -1"); + __asm __volatile ("ptrue p0.b"); + __asm __volatile ("ptrue p1.b"); + __asm __volatile ("ptrue p2.b"); + __asm __volatile ("ptrue p3.b"); + __asm __volatile ("ptrue p4.b"); + __asm __volatile ("ptrue p5.b"); + __asm __volatile ("ptrue p6.b"); + __asm __volatile ("ptrue p7.b"); + __asm __volatile ("ptrue p8.b"); + __asm __volatile ("ptrue p9.b"); + __asm __volatile ("ptrue p10.b"); + __asm __volatile ("ptrue p11.b"); + __asm __volatile ("ptrue p12.b"); + __asm __volatile ("ptrue p13.b"); + __asm __volatile ("ptrue p14.b"); + __asm __volatile ("ptrue p15.b"); + __asm __volatile ("setffr"); +} + +static int get_vl_size () +{ + int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SVE_GET_VL (%d)", res); + return -1; + } + return (res & PR_SVE_VL_LEN_MASK); +} + +static int get_svl_size () +{ + int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SME_GET_VL (%d)\n", res); + return -1; + } + return (res & PR_SVE_VL_LEN_MASK); +} + +static int set_vl_size (int new_vl) +{ + int res = prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SVE_SET_VL (%d)\n", res); + return -1; + } + + res = get_vl_size (); + if (res != new_vl) + { + printf ("Unexpected VL value (%d)\n", res); + return -1; + } + + return res; +} + +static int set_svl_size (int new_svl) +{ + int res = prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SME_SET_VL (%d)\n", res); + return -1; + } + + res = get_svl_size (); + if (res != new_svl) + { + printf ("Unexpected SVL value (%d)\n", res); + return -1; + } + + return res; +} + +/* Enable register states based on STATE. + + 0 - FPSIMD + 1 - SVE + 2 - SSVE + 3 - ZA + 4 - ZA and SSVE. */ + +void enable_states (int state) +{ + disable_za (); + disable_sm (); + initialize_fpsimd_state (); + + if (state == 1) + { + initialize_sve_state (); + } + else if (state == 2) + { + enable_sm (); + initialize_sve_state (); + } + else if (state == 3) + { + enable_za (); + initialize_za_state (); + } + else if (state == 4) + { + enable_za (); + enable_sm (); + initialize_sve_state (); + initialize_za_state (); + } + + return; +} + +static int +test_id_to_state (int id) +{ + return id / 25; +} + +static int +test_id_to_vl (int id) +{ + return 16 << ((id / 5) % 5); +} + +static int +test_id_to_svl (int id) +{ + return 16 << (id % 5); +} + +static void +dummy () +{ +} + +int +main (int argc, char **argv) +{ + if (argc > 2) + printf ("Incorrect number of arguments passed to test.\n"); + + if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME) + { + long test_id = 0; + + /* If we have a test id passed as argument, read it now. */ + if (argc == 2) + test_id = strtol (argv[1], NULL, 0); + + dummy (); /* stop to initialize test_id */ + + int state = test_id_to_state (test_id); + int vl = test_id_to_vl (test_id); + int svl = test_id_to_svl (test_id); + + if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1) + return -1; + + enable_states (state); + + /* Also set the TPIDR2 register so we can test dumping its contents + to a core file. */ + initialize_tpidr2 (); + + char *p = 0x0; + *p = 0xff; /* crash point */ + } + else + { + printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n"); + return -1; + } + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl b/gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl new file mode 100644 index 00000000000..851e6e31ec3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl @@ -0,0 +1,188 @@ +# Copyright (C) 2023 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 this program. If not, see . +# +# Exercise core file reading/writing in the presence of SME support. +# This test exercises GDB's dumping/loading capability for Linux +# Kernel core files and for gcore core files. + +load_lib aarch64-scalable.exp + +# +# Validate that CORE_FILENAME can be read correctly and that the register +# state is sane. +# +proc check_sme_core_file { core_filename state vl svl } { + # Load the core file. + if [gdb_test "core $core_filename" \ + [multi_line \ + "Core was generated by.*\." \ + "Program terminated with signal SIGSEGV, Segmentation fault\." \ + "#0 ${::hex} in main \\(.*\\) at .*" \ + ".*p = 0xff;.* crash point .*"] \ + "load core file"] { + untested "failed to generate core file" + return -1 + } + + check_state $state $vl $svl + + # Check the value of TPIDR2 in the core file. + gdb_test "print/x \$tpidr2" " = 0xffffffffffffffff" \ + "tpidr2 contents from core file" +} + +# +# Generate two core files for EXECUTABLE, BINFILE with a test id of ID. +# STATE is the register state, VL is the SVE vector length and SVL is the +# SME vector length. +# One of the core files is generated by the kernel and the other by the +# gcore command. +# +proc generate_sme_core_files { executable binfile id state vl svl} { + # Run the program until the point where we need to adjust the + # test id. + set init_breakpoint "stop to initialize test_id" + gdb_breakpoint [gdb_get_line_number $init_breakpoint] + gdb_continue_to_breakpoint $init_breakpoint + gdb_test_no_output "set test_id = $id" + + # Run the program until just before the crash. + set crash_breakpoint "crash point" + gdb_breakpoint [gdb_get_line_number $crash_breakpoint] + gdb_continue_to_breakpoint $crash_breakpoint + gdb_test_no_output "set print repeats 1" "adjust repeat count pre-crash" + + # Adjust the register to custom values that we will check later when + # loading the core files. + check_state $state $vl $svl + + # Continue until a crash. + gdb_test "continue" \ + [multi_line \ + "Program received signal SIGSEGV, Segmentation fault\." \ + "${::hex} in main \\(.*\\) at .*" \ + ".*p = 0xff;.* crash point .*"] \ + "run to crash" + + # Generate the gcore core file. + set gcore_filename [standard_output_file "${executable}-${id}-${state}-${vl}-${svl}.gcore"] + set gcore_generated [gdb_gcore_cmd "$gcore_filename" "generate gcore file"] + +# # Continue until the end. +# gdb_test "continue" "Program terminated with signal SIGSEGV.*" \ +# "program terminated with SIGSEGV" + + # Generate a native core file. + set core_filename [core_find ${binfile} {} $id] + set core_generated [expr {$core_filename != ""}] + set native_core_name "${binfile}-${id}-${state}-${vl}-${svl}.core" + remote_exec build "mv $core_filename ${native_core_name}" + set core_filename ${native_core_name} + + # At this point we have a couple core files, the gcore one generated by GDB + # and the native one generated by the Linux Kernel. Make sure GDB can read + # both correctly. + if {$gcore_generated} { + clean_restart ${binfile} + gdb_test_no_output "set print repeats 1" \ + "adjust repeat count post-crash gcore" + + with_test_prefix "gcore corefile" { + check_sme_core_file $gcore_filename $state $vl $svl + } + } else { + fail "gcore corefile not generated" + } + + if {$core_generated} { + clean_restart ${binfile} + + gdb_test_no_output "set print repeats 1" \ + "adjust repeat count post-crash native core" + + with_test_prefix "native corefile" { + check_sme_core_file $core_filename $state $vl $svl + } + } else { + untested "native corefile not generated" + } +} + +# +# Exercise core file reading (kernel-generated core files) and writing +# (gcore command) for test id's ID_START through ID_END. +# +proc test_sme_core_file { id_start id_end } { + set compile_flags {"debug" "macros" "additional_flags=-march=armv8.5-a+sve"} + standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-core.c + set executable "${::testfile}" + if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} { + return -1 + } + set binfile [standard_output_file ${executable}] + + for {set id $id_start} {$id <= $id_end} {incr id} { + set state [test_id_to_state $id] + set vl [test_id_to_vl $id] + set svl [test_id_to_svl $id] + + set skip_unsupported 0 + if {![aarch64_supports_sve_vl $vl] + || ![aarch64_supports_sme_svl $svl]} { + # We have a vector length or streaming vector length that + # is not supported by this target. Skip to the next iteration + # since it is no use running tests for an unsupported vector + # length. + if {![aarch64_supports_sve_vl $vl]} { + verbose -log "SVE vector length $vl not supported." + } elseif {![aarch64_supports_sme_svl $svl]} { + verbose -log "SME streaming vector length $svl not supported." + } + verbose -log "Skipping test." + set skip_unsupported 1 + } + + with_test_prefix "state=${state} vl=${vl} svl=${svl}" { + # If the SVE or SME vector length is not supported, just skip + # these next tests. + if {$skip_unsupported} { + untested "unsupported configuration on target" + continue + } + + if ![runto_main] { + untested "could not run to main" + return -1 + } + + # Check if we are talking to a remote target. If so, bail out, + # as right now remote targets can't communicate vector length (vl + # or svl) changes to gdb via the RSP. When this restriction is + # lifted, we can remove this guard. + if {[gdb_is_target_remote]} { + unsupported "aarch64 sve/sme tests not supported for remote targets" + return -1 + } + + generate_sme_core_files ${executable} ${binfile} $id $state $vl $svl + } + } +} + +require is_aarch64_target +require allow_aarch64_sve_tests +require allow_aarch64_sme_tests + +test_sme_core_file $id_start $id_end diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-0.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-0.exp new file mode 100644 index 00000000000..2a4980171e7 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-0.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 16 +# SVL: 16, 32, 64, 128 +# This set covers 4 (0 ~ 3) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 0 +set id_end 3 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-1.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-1.exp new file mode 100644 index 00000000000..a58e89caab3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-1.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 16 +# SVL: 256 +# This set covers 1 (4) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 4 +set id_end 4 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-2.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-2.exp new file mode 100644 index 00000000000..8b78e9ec639 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-2.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 32 +# SVL: 16, 32, 64, 128 +# This set covers 4 (5 ~ 8) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 5 +set id_end 8 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-3.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-3.exp new file mode 100644 index 00000000000..57941758870 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-3.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 32 +# SVL: 256 +# This set covers 1 (9) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 9 +set id_end 9 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-4.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-4.exp new file mode 100644 index 00000000000..5d5e800d328 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-4.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 64 +# SVL: 16, 32, 64, 128 +# This set covers 4 (10 ~ 13) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 10 +set id_end 13 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-5.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-5.exp new file mode 100644 index 00000000000..42410d4eb20 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-5.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 64 +# SVL: 256 +# This set covers 1 (14) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 14 +set id_end 14 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-6.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-6.exp new file mode 100644 index 00000000000..36692ac31c1 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-6.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 128 +# SVL: 16, 32, 64, 128 +# This set covers 4 (15 ~ 18) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 15 +set id_end 18 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-7.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-7.exp new file mode 100644 index 00000000000..a3149e7fcae --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-7.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 128 +# SVL: 256 +# This set covers 1 (19) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 19 +set id_end 19 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-8.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-8.exp new file mode 100644 index 00000000000..1859eaf9960 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-8.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 256 +# SVL: 16, 32, 64, 128 +# This set covers 4 (20 ~ 23) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 20 +set id_end 23 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-9.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-9.exp new file mode 100644 index 00000000000..cb30fc63724 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available-9.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 256 +# SVL: 256 +# This set covers 1 (24) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 24 +set id_end 24 +source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available.c b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available.c new file mode 100644 index 00000000000..58c01d0bf9a --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available.c @@ -0,0 +1,178 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 this program. If not, see . */ + +/* Exercise various cases of reading/writing ZA contents for AArch64's + Scalable Matrix Extension. */ + +#include +#include +#include +#include +#include +#include + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +#ifndef HWCAP2_SME +#define HWCAP2_SME (1 << 23) +#endif + +#ifndef PR_SVE_SET_VL +#define PR_SVE_SET_VL 50 +#define PR_SVE_GET_VL 51 +#define PR_SVE_VL_LEN_MASK 0xffff +#endif + +#ifndef PR_SME_SET_VL +#define PR_SME_SET_VL 63 +#define PR_SME_GET_VL 64 +#define PR_SME_VL_LEN_MASK 0xffff +#endif + +static void +enable_za () +{ + /* smstart za */ + __asm __volatile (".word 0xD503457F"); +} + +static void +disable_za () +{ + /* smstop za */ + __asm __volatile (".word 0xD503447F"); +} + +static int get_vl_size () +{ + int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SVE_GET_VL (%d)\n", res); + return -1; + } + return (res & PR_SVE_VL_LEN_MASK); +} + +static int get_svl_size () +{ + int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SME_GET_VL (%d)\n", res); + return -1; + } + return (res & PR_SVE_VL_LEN_MASK); +} + +static int set_vl_size (int new_vl) +{ + int res = prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SVE_SET_VL (%d)\n", res); + return -1; + } + + res = get_vl_size (); + if (res != new_vl) + { + printf ("Unexpected VL value (%d)\n", res); + return -1; + } + + return res; +} + +static int set_svl_size (int new_svl) +{ + int res = prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SME_SET_VL (%d)\n", res); + return -1; + } + + res = get_svl_size (); + if (res != new_svl) + { + printf ("Unexpected SVL value (%d)\n", res); + return -1; + } + + return res; +} + +static int +test_id_to_vl (int id) +{ + return 16 << ((id / 5) % 5); +} + +static int +test_id_to_svl (int id) +{ + return 16 << (id % 5); +} + +static void +dummy () +{ +} + +int +main (int argc, char **argv) +{ + if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME) + { + int id_start = ID_START; + int id_end = ID_END; + + for (int id = id_start; id <= id_end; id++) + { + int vl = test_id_to_vl (id); + int svl = test_id_to_svl (id); + + if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1) + continue; + + enable_za (); + dummy (); /* stop 1 */ + } + + for (int id = id_start; id <= id_end; id++) + { + int vl = test_id_to_vl (id); + int svl = test_id_to_svl (id); + + if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1) + continue; + + disable_za (); + dummy (); /* stop 2 */ + } + } + else + { + printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n"); + return -1; + } + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-available.exp.tcl b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available.exp.tcl new file mode 100644 index 00000000000..71637f9cdc1 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-available.exp.tcl @@ -0,0 +1,245 @@ +# Copyright (C) 2023 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 this program. If not, see . + +# Exercise reading/writing ZA registers when there is ZA state. + +load_lib aarch64-scalable.exp + +# +# Cycle through all ZA registers and pseudo-registers and validate that their +# contents are available for vector length SVL. +# +# Make sure reading/writing to ZA registers work as expected. +# +proc check_regs { mode vl svl } { + # Check VG to make sure it is correct + set expected_vg [expr $vl / 8] + gdb_test "print \$vg" "= ${expected_vg}" + + # Check SVG to make sure it is correct + set expected_svg [expr $svl / 8] + gdb_test "print \$svg" "= ${expected_svg}" + + # If svl is adjusted by prctl, we will have ZA enabled. If gdb is + # adjusting svl, ZA will not be enabled by default. It will only be + # enabled when ZA is written to. + set za_state "= \\\[ ZA \\\]" + if {$mode == "gdb"} { + set za_state "= \\\[ \\\]" + } + + # Check SVCR. + if [gdb_test "print \$svcr" $za_state "svcr before assignments" ] { + fail "incorrect za state" + return -1 + } + + # Check the size of ZA. + set expected_za_size [expr $svl * $svl] + gdb_test "print sizeof \$za" " = $expected_za_size" + + # Check the size of Z0. + gdb_test "print sizeof \$z0" " = $vl" + + # Exercise reading/writing from/to ZA. + initialize_2d_array "\$za" 255 $svl $svl + set pattern [string_to_regexp [2d_array_value_pattern 255 $svl $svl]] + gdb_test "print \$za" " = $pattern" "read back from za" + + # Exercise reading/writing from/to the tile pseudo-registers. + set last_tile 1 + set expected_size [expr $svl * $svl] + set tile_svl $svl + set za_state "= \\\[ ZA \\\]" + foreach_with_prefix granularity {"b" "h" "s" "d" "q"} { + for {set tile 0} {$tile < $last_tile} {incr tile} { + set register_name "\$za${tile}${granularity}" + + # Test the size. + gdb_test "print sizeof ${register_name}" " = ${expected_size}" + + # Test reading/writing + initialize_2d_array $register_name 255 $tile_svl $tile_svl + + # Make sure we have ZA state. + if [gdb_test "print \$svcr" $za_state "svcr after assignment to ${register_name}" ] { + fail "incorrect za state" + return -1 + } + + set pattern [string_to_regexp [2d_array_value_pattern 255 $tile_svl $tile_svl]] + gdb_test "print $register_name" " = $pattern" "read back from $register_name" + } + set last_tile [expr $last_tile * 2] + set expected_size [expr $expected_size / 2] + set tile_svl [expr $tile_svl / 2] + } + + # Exercise reading/writing from/to the tile slice pseudo-registers. + set last_tile 1 + set last_slice $svl + set expected_size $svl + set num_elements $svl + foreach_with_prefix granularity {"b" "h" "s" "d" "q"} { + for {set tile 0} {$tile < $last_tile} {incr tile} { + for {set slice 0} {$slice < $last_slice} {incr slice} { + foreach_with_prefix direction {"h" "v"} { + set register_name "\$za${tile}${direction}${granularity}${slice}" + + # Test the size. + gdb_test "print sizeof ${register_name}" " = ${expected_size}" + + # Test reading/writing + initialize_1d_array $register_name 255 $num_elements + + # Make sure we have ZA state. + if [gdb_test "print \$svcr" $za_state "svcr after assignment of ${register_name}" ] { + fail "incorrect za state" + return -1 + } + + set pattern [string_to_regexp [1d_array_value_pattern 255 $num_elements]] + gdb_test "print $register_name" " = $pattern" "read back from $register_name" + } + } + } + set last_tile [expr $last_tile * 2] + set last_slice [expr ($last_slice / 2)] + set num_elements [expr $num_elements / 2] + } +} + +# +# Cycle through all ZA registers and pseudo-registers and validate their +# contents. +# +proc test_sme_registers_available { id_start id_end } { + + set compile_flags {"debug" "macros"} + lappend compile_flags "additional_flags=-DID_START=${id_start}" + lappend compile_flags "additional_flags=-DID_END=${id_end}" + + standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-regs-available.c + set executable "${::testfile}-${id_start}-${id_end}" + if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} { + return -1 + } + set binfile [standard_output_file ${executable}] + + if ![runto_main] { + untested "could not run to main" + return -1 + } + + # Check if we are talking to a remote target. If so, bail out, as right now + # remote targets can't communicate vector length (vl or svl) changes to gdb + # via the RSP. When this restriction is lifted, we can remove this guard. + if {[gdb_is_target_remote]} { + unsupported "aarch64 sve/sme tests not supported for remote targets" + return -1 + } + + gdb_test_no_output "set print repeats 1" + + set prctl_breakpoint "stop 1" + gdb_breakpoint [gdb_get_line_number $prctl_breakpoint] + + for {set id $id_start} {$id <= $id_end} {incr id} { + set vl [test_id_to_vl $id] + set svl [test_id_to_svl $id] + + set skip_unsupported 0 + if {![aarch64_supports_sve_vl $vl] + || ![aarch64_supports_sme_svl $svl]} { + # We have a vector length or streaming vector length that + # is not supported by this target. Skip to the next iteration + # since it is no use running tests for an unsupported vector + # length. + if {![aarch64_supports_sve_vl $vl]} { + verbose -log "SVE vector length $vl not supported." + } elseif {![aarch64_supports_sme_svl $svl]} { + verbose -log "SME streaming vector length $svl not supported." + } + verbose -log "Skipping test." + set skip_unsupported 1 + } + + set mode "prctl" + with_test_prefix "$mode, vl=${vl} svl=${svl}" { + # If the SVE or SME vector length is not supported, just skip + # these next tests. + if {$skip_unsupported} { + untested "unsupported configuration on target" + continue + } + + # Run the program until it has adjusted svl. + gdb_continue_to_breakpoint $prctl_breakpoint + check_regs $mode $vl $svl + } + } + + set non_prctl_breakpoint "stop 2" + gdb_breakpoint [gdb_get_line_number $non_prctl_breakpoint] + + for {set id $id_start} {$id <= $id_end} {incr id} { + set vl [test_id_to_vl $id] + set svl [test_id_to_svl $id] + + set skip_unsupported 0 + if {![aarch64_supports_sve_vl $vl] + || ![aarch64_supports_sme_svl $svl]} { + # We have a vector length or streaming vector length that + # is not supported by this target. Skip to the next iteration + # since it is no use running tests for an unsupported vector + # length. + if {![aarch64_supports_sve_vl $vl]} { + verbose -log "SVE vector length $vl not supported." + } elseif {![aarch64_supports_sme_svl $svl]} { + verbose -log "SME streaming vector length $svl not supported." + } + verbose -log "Skipping test." + set skip_unsupported 1 + } + + set mode "gdb" + with_test_prefix "$mode, vl=${vl} svl=${svl}" { + # If the SVE or SME vector length is not supported, just skip + # these next tests. + if {$skip_unsupported} { + untested "unsupported configuration on target" + continue + } + + # Run the program until we stop at the point where gdb should + # adjust the SVE and SME vector lengths. + gdb_continue_to_breakpoint $non_prctl_breakpoint + + # Adjust svl via gdb. + set vg_value [expr $vl / 8] + set svg_value [expr $svl / 8] + gdb_test_no_output "set \$vg = ${vg_value}" + gdb_test_no_output "set \$svg = ${svg_value}" + + check_regs $mode $vl $svl + } + } +} + +require is_aarch64_target +require allow_aarch64_sve_tests +require allow_aarch64_sme_tests + +test_sme_registers_available $id_start $id_end diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-0.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-0.exp new file mode 100644 index 00000000000..ce8a7a703aa --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-0.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: FPSIMD +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (0 ~ 24) out of 125 tests. +set id_start 0 +set id_end 24 +source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-1.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-1.exp new file mode 100644 index 00000000000..092d4b20c48 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-1.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: SVE +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (25 ~ 49) out of 125 tests. +set id_start 25 +set id_end 49 +source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-2.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-2.exp new file mode 100644 index 00000000000..803d297f70d --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-2.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: SSVE +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (50 ~ 74) out of 125 tests. +set id_start 50 +set id_end 74 +source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-3.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-3.exp new file mode 100644 index 00000000000..d1307571bfa --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-3.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: ZA only +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (75 ~ 99) out of 125 tests. +set id_start 75 +set id_end 99 +source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-4.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-4.exp new file mode 100644 index 00000000000..2b84b5dcfc7 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-4.exp @@ -0,0 +1,23 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# state: ZA + SSVE +# VL: 16, 32, 64, 128, 256 +# SVL: 16, 32, 64, 128, 256 +# This set covers 25 (100 ~ 124) out of 125 tests. +set id_start 100 +set id_end 124 +source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.c b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.c new file mode 100644 index 00000000000..9bc3e9c16fc --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.c @@ -0,0 +1,366 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 this program. If not, see . */ + +/* Exercise AArch64's Scalable Vector/Matrix Extension signal frame handling + for GDB. */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +#ifndef HWCAP2_SME +#define HWCAP2_SME (1 << 23) +#endif + +#ifndef PR_SVE_SET_VL +#define PR_SVE_SET_VL 50 +#define PR_SVE_GET_VL 51 +#define PR_SVE_VL_LEN_MASK 0xffff +#endif + +#ifndef PR_SME_SET_VL +#define PR_SME_SET_VL 63 +#define PR_SME_GET_VL 64 +#define PR_SME_VL_LEN_MASK 0xffff +#endif + +static int count = 0; + +static void +handler (int sig) +{ + count++; /* handler */ +} + +static void +enable_za () +{ + /* smstart za */ + __asm __volatile (".word 0xD503457F"); +} + +static void +disable_za () +{ + /* smstop za */ + __asm __volatile (".word 0xD503447F"); +} + +static void +enable_sm () +{ + /* smstart sm */ + __asm __volatile (".word 0xD503437F"); +} + +static void +disable_sm () +{ + /* smstop sm */ + __asm __volatile (".word 0xD503427F"); +} + +static void +initialize_fpsimd_state () +{ + char buffer[16]; + + for (int i = 0; i < 16; i++) + buffer[i] = 0x55; + + __asm __volatile ("mov x0, %0\n\t" \ + : : "r" (buffer)); + + __asm __volatile ("ldr q0, [x0]"); + __asm __volatile ("ldr q1, [x0]"); + __asm __volatile ("ldr q2, [x0]"); + __asm __volatile ("ldr q3, [x0]"); + __asm __volatile ("ldr q4, [x0]"); + __asm __volatile ("ldr q5, [x0]"); + __asm __volatile ("ldr q6, [x0]"); + __asm __volatile ("ldr q7, [x0]"); + __asm __volatile ("ldr q8, [x0]"); + __asm __volatile ("ldr q9, [x0]"); + __asm __volatile ("ldr q10, [x0]"); + __asm __volatile ("ldr q11, [x0]"); + __asm __volatile ("ldr q12, [x0]"); + __asm __volatile ("ldr q13, [x0]"); + __asm __volatile ("ldr q14, [x0]"); + __asm __volatile ("ldr q15, [x0]"); + __asm __volatile ("ldr q16, [x0]"); + __asm __volatile ("ldr q17, [x0]"); + __asm __volatile ("ldr q18, [x0]"); + __asm __volatile ("ldr q19, [x0]"); + __asm __volatile ("ldr q20, [x0]"); + __asm __volatile ("ldr q21, [x0]"); + __asm __volatile ("ldr q22, [x0]"); + __asm __volatile ("ldr q23, [x0]"); + __asm __volatile ("ldr q24, [x0]"); + __asm __volatile ("ldr q25, [x0]"); + __asm __volatile ("ldr q26, [x0]"); + __asm __volatile ("ldr q27, [x0]"); + __asm __volatile ("ldr q28, [x0]"); + __asm __volatile ("ldr q29, [x0]"); + __asm __volatile ("ldr q30, [x0]"); + __asm __volatile ("ldr q31, [x0]"); +} + +static void +initialize_za_state () +{ + /* zero za */ + __asm __volatile (".word 0xC00800FF"); + + char buffer[256]; + + for (int i = 0; i < 256; i++) + buffer[i] = 0xaa; + + __asm __volatile ("mov x0, %0\n\t" \ + : : "r" (buffer)); + + /* Initialize loop boundaries. */ + __asm __volatile ("mov w12, 0"); + __asm __volatile ("mov w17, 256"); + + /* loop: ldr za[w12, 0], [x0] */ + __asm __volatile ("loop: .word 0xe1000000"); + __asm __volatile ("add w12, w12, 1"); + __asm __volatile ("cmp w12, w17"); + __asm __volatile ("bne loop"); +} + +static void +initialize_sve_state () +{ + __asm __volatile ("dup z0.b, -1"); + __asm __volatile ("dup z1.b, -1"); + __asm __volatile ("dup z2.b, -1"); + __asm __volatile ("dup z3.b, -1"); + __asm __volatile ("dup z4.b, -1"); + __asm __volatile ("dup z5.b, -1"); + __asm __volatile ("dup z6.b, -1"); + __asm __volatile ("dup z7.b, -1"); + __asm __volatile ("dup z8.b, -1"); + __asm __volatile ("dup z9.b, -1"); + __asm __volatile ("dup z10.b, -1"); + __asm __volatile ("dup z11.b, -1"); + __asm __volatile ("dup z12.b, -1"); + __asm __volatile ("dup z13.b, -1"); + __asm __volatile ("dup z14.b, -1"); + __asm __volatile ("dup z15.b, -1"); + __asm __volatile ("dup z16.b, -1"); + __asm __volatile ("dup z17.b, -1"); + __asm __volatile ("dup z18.b, -1"); + __asm __volatile ("dup z19.b, -1"); + __asm __volatile ("dup z20.b, -1"); + __asm __volatile ("dup z21.b, -1"); + __asm __volatile ("dup z22.b, -1"); + __asm __volatile ("dup z23.b, -1"); + __asm __volatile ("dup z24.b, -1"); + __asm __volatile ("dup z25.b, -1"); + __asm __volatile ("dup z26.b, -1"); + __asm __volatile ("dup z27.b, -1"); + __asm __volatile ("dup z28.b, -1"); + __asm __volatile ("dup z29.b, -1"); + __asm __volatile ("dup z30.b, -1"); + __asm __volatile ("dup z31.b, -1"); + __asm __volatile ("ptrue p0.b"); + __asm __volatile ("ptrue p1.b"); + __asm __volatile ("ptrue p2.b"); + __asm __volatile ("ptrue p3.b"); + __asm __volatile ("ptrue p4.b"); + __asm __volatile ("ptrue p5.b"); + __asm __volatile ("ptrue p6.b"); + __asm __volatile ("ptrue p7.b"); + __asm __volatile ("ptrue p8.b"); + __asm __volatile ("ptrue p9.b"); + __asm __volatile ("ptrue p10.b"); + __asm __volatile ("ptrue p11.b"); + __asm __volatile ("ptrue p12.b"); + __asm __volatile ("ptrue p13.b"); + __asm __volatile ("ptrue p14.b"); + __asm __volatile ("ptrue p15.b"); + __asm __volatile ("setffr"); +} + +static int get_vl_size () +{ + int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SVE_GET_VL (%d)\n", res); + return -1; + } + return (res & PR_SVE_VL_LEN_MASK); +} + +static int get_svl_size () +{ + int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SME_GET_VL (%d)\n", res); + return -1; + } + return (res & PR_SVE_VL_LEN_MASK); +} + +static int set_vl_size (int new_vl) +{ + int res = prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SVE_SET_VL (%d)\n", res); + return -1; + } + + res = get_vl_size (); + if (res != new_vl) + { + printf ("Unexpected VL value (%d)\n", res); + return -1; + } + + return res; +} + +static int set_svl_size (int new_svl) +{ + int res = prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SME_SET_VL (%d)\n", res); + return -1; + } + + res = get_svl_size (); + if (res != new_svl) + { + printf ("Unexpected SVL value (%d)\n", res); + return -1; + } + + return res; +} + +/* Enable register states based on STATE. + + 0 - FPSIMD + 1 - SVE + 2 - SSVE + 3 - ZA + 4 - ZA and SSVE. */ + +void enable_states (int state) +{ + disable_za (); + disable_sm (); + initialize_fpsimd_state (); + + if (state == 1) + { + initialize_sve_state (); + } + else if (state == 2) + { + enable_sm (); + initialize_sve_state (); + } + else if (state == 3) + { + enable_za (); + initialize_za_state (); + } + else if (state == 4) + { + enable_za (); + enable_sm (); + initialize_sve_state (); + initialize_za_state (); + } + + return; +} + +static int +test_id_to_state (int id) +{ + return (id / 25); +} + +static int +test_id_to_vl (int id) +{ + return 16 << ((id / 5) % 5); +} + +static int +test_id_to_svl (int id) +{ + return 16 << (id % 5); +} + +static void +dummy () +{ +} + +int +main (int argc, char **argv) +{ + if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME) + { + int id_start = ID_START; + int id_end = ID_END; +#ifdef SIGILL + signal (SIGILL, handler); +#endif + + int signal_count = 0; + for (int id = id_start; id <= id_end; id++) + { + int state = test_id_to_state (id); + int vl = test_id_to_vl (id); + int svl = test_id_to_svl (id); + + if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1) + continue; + + signal_count++; + enable_states (state); + dummy (); /* stop before SIGILL */ + __asm __volatile (".word 0xDEADBEEF"); /* illegal instruction */ + while (signal_count != count); + } + } + else + { + printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n"); + return -1; + } + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.exp.tcl b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.exp.tcl new file mode 100644 index 00000000000..c062e200edf --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.exp.tcl @@ -0,0 +1,179 @@ +# Copyright (C) 2023 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 this program. If not, see . + +# Exercise restoring SME/TPIDR2 state from a signal frame. + +load_lib aarch64-scalable.exp + +# +# Validate the state of registers in the signal frame for various states. +# +proc test_sme_registers_sigframe { id_start id_end } { + + set compile_flags {"debug" "macros"} + lappend compile_flags "additional_flags=-march=armv8.5-a+sve" + lappend compile_flags "additional_flags=-DID_START=${id_start}" + lappend compile_flags "additional_flags=-DID_END=${id_end}" + + standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-regs-sigframe.c + set executable "${::testfile}-${id_start}-${id_end}" + if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} { + return -1 + } + set binfile [standard_output_file ${executable}] + + if ![runto_main] { + untested "could not run to main" + return -1 + } + + # Check if we are talking to a remote target. If so, bail out, as right now + # remote targets can't communicate vector length (vl or svl) changes to gdb + # via the RSP. When this restriction is lifted, we can remove this guard. + if {[gdb_is_target_remote]} { + unsupported "aarch64 sve/sme tests not supported for remote targets" + return -1 + } + + set sigill_breakpoint "stop before SIGILL" + set handler_breakpoint "handler" + gdb_breakpoint [gdb_get_line_number $sigill_breakpoint] + gdb_breakpoint [gdb_get_line_number $handler_breakpoint] + + for {set id $id_start} {$id <= $id_end} {incr id} { + set state [test_id_to_state $id] + set vl [test_id_to_vl $id] + set svl [test_id_to_svl $id] + + set skip_unsupported 0 + if {![aarch64_supports_sve_vl $vl] + || ![aarch64_supports_sme_svl $svl]} { + # We have a vector length or streaming vector length that + # is not supported by this target. Skip to the next iteration + # since it is no use running tests for an unsupported vector + # length. + if {![aarch64_supports_sve_vl $vl]} { + verbose -log "SVE vector length $vl not supported." + } elseif {![aarch64_supports_sme_svl $svl]} { + verbose -log "SME streaming vector length $svl not supported." + } + verbose -log "Skipping test." + set skip_unsupported 1 + } + + with_test_prefix "state=${state} vl=${vl} svl=${svl}" { + + # If the SVE or SME vector length is not supported, just skip + # these next tests. + if {$skip_unsupported} { + untested "unsupported configuration on target" + continue + } + + # Run the program until it has adjusted the svl. + if [gdb_continue_to_breakpoint $sigill_breakpoint] { + return -1 + } + + # Check SVG to make sure it is correct + set expected_svg [expr $svl / 8] + gdb_test "print \$svg" "= ${expected_svg}" + + # Check the size of ZA. + set expected_za_size [expr $svl * $svl] + gdb_test "print sizeof \$za" " = $expected_za_size" + + # Check the value of SVCR. + gdb_test "print \$svcr" [get_svcr_value $state] "svcr before signal" + + # Handle SME ZA initialization and state. + set byte 0 + if { $state == "za" || $state == "za_ssve" } { + set byte 170 + } + + # Set the expected ZA pattern. + set za_pattern [string_to_regexp [2d_array_value_pattern $byte $svl $svl]] + + # Handle SVE/SSVE initialization and state. + set sve_vl $svl + if { $state == "ssve" || $state == "za_ssve" } { + # SVE state comes from SSVE. + set sve_vl $svl + } else { + # SVE state comes from regular SVE. + set sve_vl $vl + } + + # Initialize the SVE state. + set sve_pattern [string_to_regexp [sve_value_pattern $state $sve_vl 85 255]] + for {set row 0} {$row < 32} {incr row} { + set register_name "\$z${row}\.b\.u" + gdb_test "print sizeof $register_name" " = $sve_vl" "size of $register_name" + gdb_test "print $register_name" $sve_pattern "read back from $register_name" + } + + # Print ZA to check its value. + gdb_test "print \$za" $za_pattern "read back from za" + + # Test TPIDR2 restore from signal frame as well. + gdb_test_no_output "set \$tpidr2=0x0102030405060708" + + # Run to the illegal instruction. + if [gdb_test "continue" "Continuing\.\r\n\r\nProgram received signal SIGILL, Illegal instruction\..*in main.*"] { + return + } + + # Skip the illegal instruction. The signal handler will be called after we continue. + gdb_test_no_output "set \$pc=\$pc+4" + # Continue to the signal handler. + if [gdb_continue_to_breakpoint $handler_breakpoint] { + return -1 + } + + # Modify TPIDR2 so it is different from its value past the signal + # frame. + gdb_test_no_output "set \$tpidr2 = 0x0" + + # Select the frame that contains "main". + gdb_test "frame 2" "#2.* main \\\(.*\\\) at.*" + + for {set row 0} {$row < 32} {incr row} { + set register_name "\$z${row}\.b\.u" + gdb_test "print sizeof $register_name" " = $sve_vl" "size of $register_name in the signal frame" + gdb_test "print $register_name" $sve_pattern "$register_name contents from signal frame" + } + + # Check the size of ZA in the signal frame. + set expected_za_size [expr $svl * $svl] + gdb_test "print sizeof \$za" " = $expected_za_size" "size of za in signal frame" + + # Check the value of SVCR in the signal frame. + gdb_test "print \$svcr" [get_svcr_value $state] "svcr from signal frame" + + # Check the value of ZA in the signal frame. + gdb_test "print \$za" $za_pattern "za contents from signal frame" + + # Check the value of TPIDR2 in the signal frame. + gdb_test "print/x \$tpidr2" " = 0x102030405060708" "tpidr2 contents from signal frame" + } + } +} + +require is_aarch64_target +require allow_aarch64_sve_tests +require allow_aarch64_sme_tests + +test_sme_registers_sigframe $id_start $id_end diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-0.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-0.exp new file mode 100644 index 00000000000..835f28950df --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-0.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 16 +# SVL: 16, 32, 64, 128 +# This set covers 4 (0 ~ 3) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 0 +set id_end 3 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-1.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-1.exp new file mode 100644 index 00000000000..73ec3f67269 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-1.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 16 +# SVL: 256 +# This set covers 1 (4) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 4 +set id_end 4 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-2.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-2.exp new file mode 100644 index 00000000000..4d223ef4070 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-2.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 32 +# SVL: 16, 32, 64, 128 +# This set covers 4 (5 ~ 8) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 5 +set id_end 8 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-3.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-3.exp new file mode 100644 index 00000000000..3a26cd36975 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-3.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 32 +# SVL: 256 +# This set covers 1 (9) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 9 +set id_end 9 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-4.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-4.exp new file mode 100644 index 00000000000..c8e73b7cf73 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-4.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 64 +# SVL: 16, 32, 64, 128 +# This set covers 4 (10 ~ 13) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 10 +set id_end 13 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-5.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-5.exp new file mode 100644 index 00000000000..7b9f908b256 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-5.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 64 +# SVL: 256 +# This set covers 1 (14) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 14 +set id_end 14 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-6.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-6.exp new file mode 100644 index 00000000000..7a3d52f4333 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-6.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 128 +# SVL: 16, 32, 64, 128 +# This set covers 4 (15 ~ 18) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 15 +set id_end 18 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-7.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-7.exp new file mode 100644 index 00000000000..03cff0a0fe8 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-7.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 128 +# SVL: 256 +# This set covers 1 (19) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 19 +set id_end 19 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-8.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-8.exp new file mode 100644 index 00000000000..2379f3e79b4 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-8.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 256 +# SVL: 16, 32, 64, 128 +# This set covers 4 (20 ~ 23) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 20 +set id_end 23 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-9.exp b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-9.exp new file mode 100644 index 00000000000..623e75b1f64 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-9.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Exercise tests with the following parameters: +# VL: 256 +# SVL: 256 +# This set covers 1 (24) out of 25 tests. +# +# These tests are split this way for parallelization and for performance +# reasons. +# +set id_start 24 +set id_end 24 +source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.c b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.c new file mode 100644 index 00000000000..9c844c91c7c --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.c @@ -0,0 +1,152 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 this program. If not, see . */ + +/* Exercise various cases of ZA contents not being available for AArch64's + Scalable Matrix Extension. */ + +#include +#include +#include +#include +#include + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +#ifndef HWCAP2_SME +#define HWCAP2_SME (1 << 23) +#endif + +#ifndef PR_SVE_SET_VL +#define PR_SVE_SET_VL 50 +#define PR_SVE_GET_VL 51 +#define PR_SVE_VL_LEN_MASK 0xffff +#endif + +#ifndef PR_SME_SET_VL +#define PR_SME_SET_VL 63 +#define PR_SME_GET_VL 64 +#define PR_SME_VL_LEN_MASK 0xffff +#endif + +static int get_vl_size () +{ + int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SVE_GET_VL (%d)\n", res); + return -1; + } + return (res & PR_SVE_VL_LEN_MASK); +} + +static int get_svl_size () +{ + int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SME_GET_VL (%d)\n", res); + return -1; + } + return (res & PR_SVE_VL_LEN_MASK); +} + +static int set_vl_size (int new_vl) +{ + int res = prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SVE_SET_VL (%d)\n", res); + return -1; + } + + res = get_vl_size (); + if (res != new_vl) + { + printf ("Unexpected VL value (%d)\n", res); + return -1; + } + + return res; +} + +static int set_svl_size (int new_svl) +{ + int res = prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0); + if (res < 0) + { + printf ("FAILED to PR_SME_SET_VL (%d)\n", res); + return -1; + } + + res = get_svl_size (); + if (res != new_svl) + { + printf ("Unexpected SVL value (%d)\n", res); + return -1; + } + + return res; +} + +static int +test_id_to_vl (int id) +{ + return 16 << ((id / 5) % 5); +} + +static int +test_id_to_svl (int id) +{ + return 16 << (id % 5); +} + +static void +dummy () +{ +} + +int +main (int argc, char **argv) +{ + if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME) + { + int id_start = ID_START; + int id_end = ID_END; + + for (int id = id_start; id <= id_end; id++) + { + int vl = test_id_to_vl (id); + int svl = test_id_to_svl (id); + + if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1) + continue; + + dummy (); /* stop 1 */ + } + + dummy (); /* stop 2 */ + } + else + { + printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n"); + return -1; + } + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.exp.tcl b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.exp.tcl new file mode 100644 index 00000000000..1a5ebf1cdaa --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.exp.tcl @@ -0,0 +1,212 @@ +# Copyright (C) 2023 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 this program. If not, see . + +# Exercise the following: +# - Printing ZA registers when there is no ZA state. +# - Setting values of ZA registers when there is no ZA state. +# - Validating ZA state is activated when we write to ZA registers. + +load_lib aarch64-scalable.exp + +# +# Validate that the ZA registers have the expected state. +# +proc_with_prefix check_regs { vl svl } { + # Check VG to make sure it is correct + set expected_vg [expr $vl / 8] + gdb_test "print \$vg" "= ${expected_vg}" + + # Check SVG to make sure it is correct + set expected_svg [expr $svl / 8] + gdb_test "print \$svg" "= ${expected_svg}" + + # Make sure there is no SM or ZA state. + if [gdb_test "print \$svcr" "= \\\[ \\\]"] { + fail "incorrect ZA state" + return -1 + } + + # Check the size of ZA. + set expected_za_size [expr $svl * $svl] + gdb_test "print sizeof \$za" " = $expected_za_size" + + # Check the size of Z0. + gdb_test "print sizeof \$z0" " = $vl" + + # Set the expected ZA pattern. + set za_pattern [string_to_regexp [2d_array_value_pattern 0 $svl $svl]] + + # Check ZA. + gdb_test "print \$za" $za_pattern + + # Exercise reading/writing the tile slice pseudo-registers. + set last_tile 1 + set last_slice $svl + set elements $svl + set expected_size $svl + foreach_with_prefix granularity {"b" "h" "s" "d" "q"} { + set pattern [string_to_regexp [1d_array_value_pattern 0 $elements]] + for {set tile 0} {$tile < $last_tile} {incr tile} { + for {set slice 0} {$slice < $last_slice} {incr slice} { + foreach_with_prefix direction {"h" "v"} { + set register_name "\$za${tile}${direction}${granularity}${slice}" + # Test the size. + gdb_test "print sizeof ${register_name}" " = ${expected_size}" + gdb_test "print ${register_name}" $pattern + } + } + } + set last_tile [expr $last_tile * 2] + set last_slice [expr ($last_slice / 2)] + set elements [expr ($elements / 2)] + } + + # Exercise reading/writing the tile pseudo-registers. + set last_tile 1 + set elements $svl + set expected_size [expr $svl * $svl] + foreach_with_prefix granularity {"b" "h" "s" "d" "q"} { + set pattern [string_to_regexp [2d_array_value_pattern 0 $elements $elements]] + for {set tile 0} {$tile < $last_tile} {incr tile} { + set register_name "\$za${tile}${granularity}" + # Test the size. + gdb_test "print sizeof ${register_name}" " = ${expected_size}" + gdb_test "print ${register_name}" $pattern + } + set last_tile [expr $last_tile * 2] + set expected_size [expr $expected_size / 2] + set elements [expr ($elements / 2)] + } +} + +# +# Cycle through all ZA registers and pseudo-registers and validate that their +# contents are unavailable (zeroed out) for vector length SVL. +# +proc test_sme_registers_unavailable { id_start id_end } { + + set compile_flags {"debug" "macros"} + lappend compile_flags "additional_flags=-DID_START=${id_start}" + lappend compile_flags "additional_flags=-DID_END=${id_end}" + + standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-regs-unavailable.c + set executable "${::testfile}-${id_start}-${id_end}" + if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} { + return -1 + } + set binfile [standard_output_file ${executable}] + + if ![runto_main] { + untested "could not run to main" + return -1 + } + + # Check if we are talking to a remote target. If so, bail out, as right now + # remote targets can't communicate vector length (vl or svl) changes to gdb + # via the RSP. When this restriction is lifted, we can remove this guard. + if {[gdb_is_target_remote]} { + unsupported "aarch64 sve/sme tests not supported for remote targets" + return -1 + } + + gdb_test_no_output "set print repeats 1" + + set prctl_breakpoint "stop 1" + gdb_breakpoint [gdb_get_line_number $prctl_breakpoint] + + for {set id $id_start} {$id <= $id_end} {incr id} { + set vl [test_id_to_vl $id] + set svl [test_id_to_svl $id] + + set skip_unsupported 0 + if {![aarch64_supports_sve_vl $vl] + || ![aarch64_supports_sme_svl $svl]} { + # We have a vector length or streaming vector length that + # is not supported by this target. Skip to the next iteration + # since it is no use running tests for an unsupported vector + # length. + if {![aarch64_supports_sve_vl $vl]} { + verbose -log "SVE vector length $vl not supported." + } elseif {![aarch64_supports_sme_svl $svl]} { + verbose -log "SME streaming vector length $svl not supported." + } + verbose -log "Skipping test." + set skip_unsupported 1 + } + + with_test_prefix "prctl, vl=${vl} svl=${svl}" { + # If the SVE or SME vector length is not supported, just skip + # these next tests. + if {$skip_unsupported} { + untested "unsupported configuration on target" + continue + } + + # Run the program until it has adjusted svl. + gdb_continue_to_breakpoint $prctl_breakpoint + + check_regs $vl $svl + } + } + + set non_prctl_breakpoint "stop 2" + gdb_breakpoint [gdb_get_line_number $non_prctl_breakpoint] + gdb_continue_to_breakpoint $non_prctl_breakpoint + + for {set id $id_start} {$id <= $id_end} {incr id} { + set vl [test_id_to_vl $id] + set svl [test_id_to_svl $id] + + set skip_unsupported 0 + if {![aarch64_supports_sve_vl $vl] + || ![aarch64_supports_sme_svl $svl]} { + # We have a vector length or streaming vector length that + # is not supported by this target. Skip to the next iteration + # since it is no use running tests for an unsupported vector + # length. + if {![aarch64_supports_sve_vl $vl]} { + verbose -log "SVE vector length $vl not supported." + } elseif {![aarch64_supports_sme_svl $svl]} { + verbose -log "SME streaming vector length $svl not supported." + } + verbose -log "Skipping test." + set skip_unsupported 1 + } + + with_test_prefix "gdb, vl=${vl} svl=${svl}" { + + # If the SVE or SME vector length is not supported, just skip + # these next tests. + if {$skip_unsupported} { + untested "unsupported configuration on target" + continue + } + + # Adjust vg and svg. + set vg_value [expr $vl / 8] + set svg_value [expr $svl / 8] + gdb_test_no_output "set \$vg = ${vg_value}" + gdb_test_no_output "set \$svg = ${svg_value}" + + check_regs $vl $svl + } + } +} + +require is_aarch64_target +require allow_aarch64_sve_tests +require allow_aarch64_sme_tests + +test_sme_registers_unavailable $id_start $id_end diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-sanity.c b/gdb/testsuite/gdb.arch/aarch64-sme-sanity.c new file mode 100644 index 00000000000..694de0626d2 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-sanity.c @@ -0,0 +1,249 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 this program. If not, see . */ + +/* Sanity test to exercise AArch64's Scalable Vector/Matrix Extension basic + functionality. It cycles through different combinations of state and + initializes different register sets. */ + +#include +#include +#include +#include +#include + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +#ifndef HWCAP2_SME +#define HWCAP2_SME (1 << 23) +#endif + +static void +enable_za () +{ + /* smstart za */ + __asm __volatile (".word 0xD503457F"); +} + +static void +disable_za () +{ + /* smstop za */ + __asm __volatile (".word 0xD503447F"); +} + +static void +enable_sm () +{ + /* smstart sm */ + __asm __volatile (".word 0xD503437F"); +} + +static void +disable_sm () +{ + /* smstop sm */ + __asm __volatile (".word 0xD503427F"); +} + +static void +initialize_fpsimd_state () +{ + char buffer[16]; + + for (int i = 0; i < 16; i++) + buffer[i] = 0x55; + + __asm __volatile ("mov x0, %0\n\t" \ + : : "r" (buffer)); + + __asm __volatile ("ldr q0, [x0]"); + __asm __volatile ("ldr q1, [x0]"); + __asm __volatile ("ldr q2, [x0]"); + __asm __volatile ("ldr q3, [x0]"); + __asm __volatile ("ldr q4, [x0]"); + __asm __volatile ("ldr q5, [x0]"); + __asm __volatile ("ldr q6, [x0]"); + __asm __volatile ("ldr q7, [x0]"); + __asm __volatile ("ldr q8, [x0]"); + __asm __volatile ("ldr q9, [x0]"); + __asm __volatile ("ldr q10, [x0]"); + __asm __volatile ("ldr q11, [x0]"); + __asm __volatile ("ldr q12, [x0]"); + __asm __volatile ("ldr q13, [x0]"); + __asm __volatile ("ldr q14, [x0]"); + __asm __volatile ("ldr q15, [x0]"); + __asm __volatile ("ldr q16, [x0]"); + __asm __volatile ("ldr q17, [x0]"); + __asm __volatile ("ldr q18, [x0]"); + __asm __volatile ("ldr q19, [x0]"); + __asm __volatile ("ldr q20, [x0]"); + __asm __volatile ("ldr q21, [x0]"); + __asm __volatile ("ldr q22, [x0]"); + __asm __volatile ("ldr q23, [x0]"); + __asm __volatile ("ldr q24, [x0]"); + __asm __volatile ("ldr q25, [x0]"); + __asm __volatile ("ldr q26, [x0]"); + __asm __volatile ("ldr q27, [x0]"); + __asm __volatile ("ldr q28, [x0]"); + __asm __volatile ("ldr q29, [x0]"); + __asm __volatile ("ldr q30, [x0]"); + __asm __volatile ("ldr q31, [x0]"); +} + +static void +initialize_za_state () +{ + /* zero za */ + __asm __volatile (".word 0xC00800FF"); + + char buffer[256]; + + for (int i = 0; i < 256; i++) + buffer[i] = 0xaa; + + __asm __volatile ("mov x0, %0\n\t" \ + : : "r" (buffer)); + + /* Initialize loop boundaries. */ + __asm __volatile ("mov w12, 0"); + __asm __volatile ("mov w17, 256"); + + /* loop: ldr za[w12, 0], [x0] */ + __asm __volatile ("loop: .word 0xe1000000"); + __asm __volatile ("add w12, w12, 1"); + __asm __volatile ("cmp w12, w17"); + __asm __volatile ("bne loop"); +} + +static void +initialize_sve_state () +{ + __asm __volatile ("dup z0.b, -1"); + __asm __volatile ("dup z1.b, -1"); + __asm __volatile ("dup z2.b, -1"); + __asm __volatile ("dup z3.b, -1"); + __asm __volatile ("dup z4.b, -1"); + __asm __volatile ("dup z5.b, -1"); + __asm __volatile ("dup z6.b, -1"); + __asm __volatile ("dup z7.b, -1"); + __asm __volatile ("dup z8.b, -1"); + __asm __volatile ("dup z9.b, -1"); + __asm __volatile ("dup z10.b, -1"); + __asm __volatile ("dup z11.b, -1"); + __asm __volatile ("dup z12.b, -1"); + __asm __volatile ("dup z13.b, -1"); + __asm __volatile ("dup z14.b, -1"); + __asm __volatile ("dup z15.b, -1"); + __asm __volatile ("dup z16.b, -1"); + __asm __volatile ("dup z17.b, -1"); + __asm __volatile ("dup z18.b, -1"); + __asm __volatile ("dup z19.b, -1"); + __asm __volatile ("dup z20.b, -1"); + __asm __volatile ("dup z21.b, -1"); + __asm __volatile ("dup z22.b, -1"); + __asm __volatile ("dup z23.b, -1"); + __asm __volatile ("dup z24.b, -1"); + __asm __volatile ("dup z25.b, -1"); + __asm __volatile ("dup z26.b, -1"); + __asm __volatile ("dup z27.b, -1"); + __asm __volatile ("dup z28.b, -1"); + __asm __volatile ("dup z29.b, -1"); + __asm __volatile ("dup z30.b, -1"); + __asm __volatile ("dup z31.b, -1"); + __asm __volatile ("ptrue p0.b"); + __asm __volatile ("ptrue p1.b"); + __asm __volatile ("ptrue p2.b"); + __asm __volatile ("ptrue p3.b"); + __asm __volatile ("ptrue p4.b"); + __asm __volatile ("ptrue p5.b"); + __asm __volatile ("ptrue p6.b"); + __asm __volatile ("ptrue p7.b"); + __asm __volatile ("ptrue p8.b"); + __asm __volatile ("ptrue p9.b"); + __asm __volatile ("ptrue p10.b"); + __asm __volatile ("ptrue p11.b"); + __asm __volatile ("ptrue p12.b"); + __asm __volatile ("ptrue p13.b"); + __asm __volatile ("ptrue p14.b"); + __asm __volatile ("ptrue p15.b"); + __asm __volatile ("setffr"); +} + +/* Enable register states based on STATE. + + 0 - FPSIMD + 1 - SVE + 2 - SSVE + 3 - ZA + 4 - ZA and SSVE. */ + +void enable_states (int state) +{ + disable_za (); + disable_sm (); + initialize_fpsimd_state (); + + if (state == 1) + { + initialize_sve_state (); + } + else if (state == 2) + { + enable_sm (); + initialize_sve_state (); + } + else if (state == 3) + { + enable_za (); + initialize_za_state (); + } + else if (state == 4) + { + enable_za (); + enable_sm (); + initialize_sve_state (); + initialize_za_state (); + } + + return; +} + +void dummy () +{ +} + +int +main (int argc, char **argv) +{ + if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME) + { + for (int state = 0; state < 5; state++) + { + enable_states (state); + dummy (); /* stop here */ + } + } + else + { + printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n"); + return -1; + } + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-sanity.exp b/gdb/testsuite/gdb.arch/aarch64-sme-sanity.exp new file mode 100644 index 00000000000..3369976ef9b --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sme-sanity.exp @@ -0,0 +1,72 @@ +# Copyright (C) 2023 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 this program. If not, see . +# +# Sanity check for AArch64 Scalable Vector/Matrix Extensions functionality. + +load_lib aarch64-scalable.exp + +# +# Run a series of basic checks for SVE/SME states. +# +proc sanity_check { vl svl } { + # Run the program until the point where we start initializing the different + # register states. + set state_breakpoint "stop here" + gdb_breakpoint [gdb_get_line_number $state_breakpoint] + + for {set id 0} {$id < 5} {incr id} { + set state [state_id_to_state_string $id] + + with_test_prefix "state=${state} vl=${vl} svl=${svl}" { + gdb_continue_to_breakpoint $state_breakpoint + check_state $state $vl $svl + } + } +} + +require is_aarch64_target +require allow_aarch64_sve_tests +require allow_aarch64_sme_tests + +set compile_flags {"debug" "macros" "additional_flags=-march=armv8.5-a+sve"} +standard_testfile +if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} ${compile_flags}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +# Check if we are talking to a remote target. If so, bail out, as right now +# remote targets can't communicate vector length (vl or svl) changes to gdb +# via the RSP. When this restriction is lifted, we can remove this guard. +if {[gdb_is_target_remote]} { + unsupported "aarch64 sve/sme tests not supported for remote targets" + return -1 +} + +# Adjust the repeat count for the test. +gdb_test_no_output "set print repeats 1" "adjust repeat count" + +# Fetch both the vector length and the streaming vector length the target +# system is using. We do not force any vector lengths and do not change +# it mid-execution. +set vl [expr [get_valueof "" "\$vg" "0" "fetch value of vl"] * 8] +set svl [expr [get_valueof "" "\$svg" "0" "fetch value of svl"] * 8] + +# Now we are at the point where we can start checking state and moving the +# testcase forward. +sanity_check $vl $svl diff --git a/gdb/testsuite/lib/aarch64-scalable.exp b/gdb/testsuite/lib/aarch64-scalable.exp new file mode 100644 index 00000000000..5512fcb9d1c --- /dev/null +++ b/gdb/testsuite/lib/aarch64-scalable.exp @@ -0,0 +1,239 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Support routines for aarch64 scalable extension tests + +# Load generic aarch64 test dependencies. +load_lib aarch64.exp + +# +# Return a regular expression that matches what gdb would print for a +# SVE Z register of length VL in state STATE. The Z register should be filled +# with BYTE_SVE and the FPSIMD registers should be filled with BYTE_FPSIMD. +# +# The pattern is of the form +# +# {BYTE_FPSIMD } +# +# or +# +# {BYTE_FPSIMD , 0 } +# +# or +# +# {BYTE_SVE } +# +proc sve_value_pattern { state vl byte_fpsimd byte_sve } { + set brace_open "{" + set brace_close "}" + + append data $brace_open + if { $state == "fpsimd" || $state == "za" } { + if { $vl > 16 } { + set sve_repeat_count [expr $vl - 16] + append data "$byte_fpsimd , 0 " + } else { + append data "$byte_fpsimd " + } + } else { + append data "$byte_sve " + } + append data $brace_close + + verbose -log "sve_value_pattern pattern string is..." + verbose -log $data + return $data +} + +# +# Return the SVCR value based on STATE. +# SVCR is only available when SME is available. +# +proc get_svcr_value { state } { + if { $state == "ssve" } { + return "= \\\[ SM \\\]" + } elseif { $state == "za" } { + return "= \\\[ ZA \\\]" + } elseif { $state == "za_ssve" } { + return "= \\\[ SM ZA \\\]" + } + + return "= \\\[ \\\]" +} + +# +# Return the state string based on STATE +# +proc state_id_to_state_string { state } { + if {$state == 0} { + return "fpsimd" + } elseif {$state == 1} { + return "sve" + } elseif {$state == 2} { + return "ssve" + } elseif {$state == 3} { + return "za" + } elseif {$state == 4} { + return "za_ssve" + } +} + +# +# Given a test ID, return the string representing the register state. +# The state is one of fpsimd, sve, ssve, za and za_ssve. +# +proc test_id_to_state { id } { + set state [expr $id / 25] + + return [state_id_to_state_string $state] +} + +# +# Given a test ID, return the associated vector length. +# +proc test_id_to_vl { id } { + return [expr 16 << (($id / 5) % 5)] +} + +# +# Given a test ID, return the associated streaming vector length. +# +proc test_id_to_svl { id } { + return [expr 16 << ($id % 5)] +} + +# +# Validate the values of the SVE registers. +# +proc check_sve_regs { byte state vl svl } { + + # If streaming mode is enabled, the vector length is the streaming + # vector length. + set z_pattern "" + set z_size 0 + if {$state == "ssve" || $state == "za_ssve"} { + set z_pattern [string_to_regexp [1d_array_value_pattern $byte $svl]] + set z_size $svl + } else { + set z_size $vl + + if {$state == "fpsimd" || $state == "za"} { + # If there is no SVE/SSVE state, the contents of the Z/P/FFR registers + # are zero. + if {$vl == 16} { + set z_pattern [string_to_regexp [1d_array_value_pattern $byte $vl]] + } else { + set z_repeats [expr $vl - 16] + set z_pattern [string_to_regexp "{$byte , 0 }"] + } + } else { + set z_pattern [string_to_regexp [1d_array_value_pattern $byte $vl]] + } + } + set p_size [expr $z_size / 8] + + # If there is no SVE/SSVE state, the contents of the Z/P/FFR registers + # are zero. + set p_byte $byte + if {$state == "fpsimd" || $state == "za"} { + set p_byte 0 + } + set p_pattern [string_to_regexp [1d_array_value_pattern $p_byte $p_size]] + + for {set number 0} {$number < 32} {incr number} { + set register_name "\$z${number}\.b\.u" + gdb_test "print sizeof $register_name" " = $z_size" + gdb_test "print $register_name" $z_pattern + } + + for {set number 0} {$number < 16} {incr number} { + set register_name "\$p${number}" + gdb_test "print sizeof $register_name" " = $p_size" + gdb_test "print $register_name" $p_pattern + } + + gdb_test "print \$ffr" $p_pattern +} + +# +# Validate the values of the SME registers. +# +proc check_sme_regs { byte state svl } { + # ZA contents are only available when the ZA state is enabled. Otherwise + # the ZA contents are unavailable (zeroed out). + set za_pattern "" + set expected_za_size [expr $svl * $svl] + + if {$state != "za" && $state != "za_ssve"} { + set byte 0 + } + + set za_pattern [string_to_regexp [2d_array_value_pattern $byte $svl $svl]] + + gdb_test "print sizeof \$za" " = $expected_za_size" + gdb_test "print \$za" $za_pattern +} + +# +# With register STATE, vector length VL and streaming vector length SVL, +# run some register state checks to make sure the values are the expected +# ones +# +proc check_state { state vl svl } { + # The FPSIMD registers are initialized with a value of 0x55 (85) + # for each byte. + # + # The SVE registers are initialized with a value of 0xff (255) for each + # byte, including the predicate registers and FFR. + # + # The SME (ZA) register is initialized with a value of 0xaa (170) for + # each byte. + + # Check VG to make sure it is correct + set expected_vg [expr $vl / 8] + # If streaming mode is enabled, then vg is actually svg. + if {$state == "ssve" || $state == "za_ssve"} { + set expected_vg [expr $svl / 8] + } + gdb_test "print \$vg" " = ${expected_vg}" + + # Check SVG to make sure it is correct + set expected_svg [expr $svl / 8] + gdb_test "print \$svg" " = ${expected_svg}" + + # Check the value of SVCR. + gdb_test "print \$svcr" [get_svcr_value $state] + + # When we have any SVE or SSVE state, the FPSIMD registers will have + # the same values as the SVE/SSVE Z registers. + set fpsimd_byte 85 + if {$state == "sve" || $state == "ssve" || $state == "za_ssve"} { + set fpsimd_byte 255 + } + + set sve_byte 255 + if {$state == "fpsimd" || $state == "za"} { + set sve_byte 85 + } + + # Check FPSIMD registers + check_fpsimd_regs $fpsimd_byte $state $vl $svl + # Check SVE registers + check_sve_regs $sve_byte $state $vl $svl + # Check SME registers + check_sme_regs 170 $state $svl +} + + diff --git a/gdb/testsuite/lib/aarch64-test-sme.c b/gdb/testsuite/lib/aarch64-test-sme.c new file mode 100644 index 00000000000..c123f37e0df --- /dev/null +++ b/gdb/testsuite/lib/aarch64-test-sme.c @@ -0,0 +1,90 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 this program. If not, see . */ + +/* AArch64 SME feature check. This test serves as a way for the GDB testsuite + to verify that a target supports SVE at runtime, and also reports data + about the various supported SME streaming vector lengths. */ + +#include +#include +#include +#include +#include +#include + +#ifndef HWCAP2_SME +#define HWCAP2_SME (1 << 23) +#endif + +#ifndef PR_SME_SET_VL +#define PR_SME_SET_VL 63 +#define PR_SME_GET_VL 64 +#define PR_SME_VL_LEN_MASK 0xffff +#endif + +static int get_svl_size () +{ + int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0); + + if (res < 0) + return -1; + + return (res & PR_SME_VL_LEN_MASK); +} + +static int set_svl_size (int new_svl) +{ + if (prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0) < 0) + return -1; + + if (get_svl_size () != new_svl) + return -1; + + return 0; +} + +static void +dummy () +{ +} + +#define SVL_MIN 16 +#define SVL_MAX 256 +#define SVL_INCREMENT_POWER 1 + +int +main (int argc, char **argv) +{ + /* Number of supported SME streaming vector lengths. */ + size_t supported_svl_count = 0; + /* Vector containing the various supported SME streaming vector lengths. */ + size_t supported_svl[5]; + + if (getauxval (AT_HWCAP) & HWCAP2_SME) + { + for (int svl = SVL_MIN; svl <= SVL_MAX; svl <<= SVL_INCREMENT_POWER) + { + if (set_svl_size (svl) == 0) + { + supported_svl[supported_svl_count] = svl; + supported_svl_count++; + } + } + } + + return 0; /* stop here */ +} diff --git a/gdb/testsuite/lib/aarch64-test-sve.c b/gdb/testsuite/lib/aarch64-test-sve.c new file mode 100644 index 00000000000..4673581b467 --- /dev/null +++ b/gdb/testsuite/lib/aarch64-test-sve.c @@ -0,0 +1,90 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 this program. If not, see . */ + +/* AArch64 SVE feature check. This test serves as a way for the GDB testsuite + to verify that a target supports SVE at runtime, and also reports data + about the various supported SVE vector lengths. */ + +#include +#include +#include +#include +#include +#include + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +#ifndef PR_SVE_SET_VL +#define PR_SVE_SET_VL 50 +#define PR_SVE_GET_VL 51 +#define PR_SVE_VL_LEN_MASK 0xffff +#endif + +static int get_vl_size () +{ + int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0); + + if (res < 0) + return -1; + + return (res & PR_SVE_VL_LEN_MASK); +} + +static int set_vl_size (int new_vl) +{ + if (prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0) < 0) + return -1; + + if (get_vl_size () != new_vl) + return -1; + + return 0; +} + +static void +dummy () +{ +} + +#define VL_MIN 16 +#define VL_MAX 256 +#define VL_INCREMENT 16 + +int +main (int argc, char **argv) +{ + /* Number of supported SVE vector lengths. */ + size_t supported_vl_count = 0; + /* Vector containing the various supported SVE vector lengths. */ + size_t supported_vl[16]; + + if (getauxval (AT_HWCAP) & HWCAP_SVE) + { + for (int vl = VL_MIN; vl <= VL_MAX; vl += VL_INCREMENT) + { + if (set_vl_size (vl) == 0) + { + supported_vl[supported_vl_count] = vl; + supported_vl_count++; + } + } + } + + return 0; /* stop here */ +} diff --git a/gdb/testsuite/lib/aarch64.exp b/gdb/testsuite/lib/aarch64.exp new file mode 100644 index 00000000000..cd43a4c4f77 --- /dev/null +++ b/gdb/testsuite/lib/aarch64.exp @@ -0,0 +1,153 @@ +# Copyright 2023 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 this program. If not, see . */ + +# Support routines for aarch64-specific tests + +# +# Return a regular expression that matches what gdb would print for a +# 1-dimension vector containing ELEMENTS elements of value BYTE. +# +# The pattern is of the form "{BYTE ". +# +proc 1d_array_value_pattern { byte elements } { + set brace_open "{" + set brace_close "}" + + append data $brace_open $byte + if {$elements > 1} { + append data " " + } + append data $brace_close + + verbose -log "1d_array_value_pattern Pattern string is..." + verbose -log $data + return $data +} + +# +# Return a regular expression that matches what gdb would print for a +# 2-dimension vector containing ROWS rows and COLUMNS columns of elements +# of value BYTE. +# +# The pattern is of the form +# "{{BYTE } }". +# +proc 2d_array_value_pattern { byte rows columns } { + set brace_open "{" + set brace_close "}" + + append data $brace_open [1d_array_value_pattern $byte $columns] + if {$rows > 1} { + append data " " + } + append data $brace_close + + verbose -log "2d_array_value_pattern Pattern string is..." + verbose -log $data + return $data +} + +# +# Initialize register NAME, a 1-dimension vector, with ELEMENTS elements +# by setting all elements to BYTE. ELEMENTS is limited at 256 for memory +# usage purposes. +# +# The initialization is of the form "{BYTE, BYTE, BYTE ...}". +# +proc initialize_1d_array { name byte elements } { + set brace_open "{" + set brace_close "}" + + append data $brace_open + + # Build the assignment in a single shot. + for {set element 0} {$element < $elements} {incr element} { + # Construct the initializer by appending elements to it. + append data $byte + + # If this isn't the last element, add a comma. + if {[expr $element + 1] < $elements} { + append data ", " + } + } + append data $brace_close + + verbose -log "initialization string is..." + verbose -log $data + gdb_test_no_output "set $name = $data" "write to $name" +} + +# +# Return an initializer string for a 2-dimension vector with ROWS rows and +# COLUMNS columns, initializing all elements to BYTE for register NAME. +# +# COLUMNS is limited to 256 elements for memory usage purposes. +# +# The initialization is of the form "{{BYTE, BYTE}, ..., {BYTE, BYTE}}}". +# +proc initialize_2d_array { name byte rows columns } { + set brace_open "{" + set brace_close "}" + + if {[expr $rows * $columns] <= 256} { + # Build the assignment in a single shot, as we have a maximum of 256 + # elements. + for {set row 0} {$row < $rows} {incr row} { + append data $brace_open + for {set column 0} {$column < $columns} {incr column} { + # Construct the initializer by appending elements to it. + append data $byte + + # If this isn't the last column, add a comma. + if {[expr $column + 1] < $columns} { + append data ", " + } + } + + append data $brace_close + + # If this isn't the last row, add a comma. + if {[expr $row + 1] < $rows} { + append data "," + } + } + + set data $brace_open$data + set data $data$brace_close + + verbose -log "initialization string is..." + verbose -log $data + gdb_test_no_output "set $name = $data" "write to $name" + } else { + # There are too many elements to initialize (more than 256), so we + # will do the initialization row by row. + for {set row 0} {$row < $rows} {incr row} { + initialize_1d_array "$name\[$row\]" $byte $columns + } + } +} + +# +# Validate the values of the FPSIMD registers. +# +proc check_fpsimd_regs { byte state vl svl} { + set fpsimd_pattern [string_to_regexp [1d_array_value_pattern $byte 16]] + + for {set number 0} {$number < 32} {incr number} { + set register_name "\$v${number}\.b\.u" + gdb_test "print sizeof $register_name" " = 16" + gdb_test "print $register_name" $fpsimd_pattern + } +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 1b9179401c4..cf1d4a90e55 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -4152,10 +4152,259 @@ gdb_caching_proc allow_aarch64_sve_tests {} { gdb_exit remote_file build delete $obj + # While testing for SVE support, also discover all the supported vector + # length values. + aarch64_initialize_sve_information + verbose "$me: returning $allow_sve_tests" 2 return $allow_sve_tests } +# Assuming SVE is supported by the target, run some checks to determine all +# the supported vector length values and return an array containing all of those +# values. Since this is a gdb_caching_proc, this proc will only be executed +# once. +# +# To check if a particular SVE vector length is supported, the following code +# can be used. For instance, for vl == 16: +# +# if {[aarch64_supports_sve_vl 16]} { +# verbose -log "SVE vector length 16 is supported." +# } +# +# This procedure should NEVER be called by hand, as it reinitializes the GDB +# session and will derail a test. This should be called automatically as part +# of the SVE support test routine allow_aarch64_sve_tests. Users should +# restrict themselves to calling the helper proc aarch64_supports_sve_vl. + +gdb_caching_proc aarch64_initialize_sve_information { } { + global srcdir + + set src "${srcdir}/lib/aarch64-test-sve.c" + set test_exec [standard_temp_file "aarch64-test-sve.x"] + set compile_flags "{additional_flags=-march=armv8-a+sve}" + array set supported_vl {} + + # Compile the SVE vector length test. + set result [gdb_compile $src $test_exec executable [list debug ${compile_flags} nowarnings]] + + if {$result != ""} { + verbose -log "Failed to compile SVE information gathering test." + return [array get supported_vl] + } + + clean_restart $test_exec + + if {![runto_main]} { + return [array get supported_vl] + } + + set stop_breakpoint "stop here" + gdb_breakpoint [gdb_get_line_number $stop_breakpoint $src] + gdb_continue_to_breakpoint $stop_breakpoint + + # Go through the data and extract the supported SVE vector lengths. + set vl_count [get_valueof "" "supported_vl_count" "0" \ + "fetch value of supported_vl_count"] + verbose -log "Found $vl_count supported SVE vector length values" + + for {set vl_index 0} {$vl_index < $vl_count} {incr vl_index} { + set test_vl [get_valueof "" "supported_vl\[$vl_index\]" "0" \ + "fetch value of supported_vl\[$vl_index\]"] + + # Mark this vector length as supported. + if {$test_vl != 0} { + verbose -log "Found supported SVE vector length $test_vl" + set supported_vl($test_vl) 1 + } + } + + gdb_exit + verbose -log "Cleaning up" + remote_file build delete $test_exec + + verbose -log "Done gathering information about AArch64 SVE vector lengths." + + # Return the array containing all of the supported SVE vl values. + return [array get supported_vl] +} + +# +# Return 1 if the target supports SVE vl LENGTH +# Return 0 otherwise. +# + +proc aarch64_supports_sve_vl { length } { + + # Fetch the cached array of supported SVE vl values. + array set supported_vl [aarch64_initialize_sve_information] + + # Do we have the global values cached? + if {![info exists supported_vl($length)]} { + verbose -log "Target does not support SVE vl $length" + return 0 + } + + # The target supports SVE vl LENGTH. + return 1 +} + +# Run a test on the target to see if it supports Aarch64 SME extensions. +# Return 0 if so, 1 if it does not. Note this causes a restart of GDB. + +gdb_caching_proc allow_aarch64_sme_tests {} { + global srcdir subdir gdb_prompt inferior_exited_re + + set me "allow_aarch64_sme_tests" + + if { ![is_aarch64_target]} { + return 0 + } + + set compile_flags "{additional_flags=-march=armv8-a+sme}" + + # Compile a test program containing SME instructions. + set src { + int main() { + asm volatile ("smstart za"); + return 0; + } + } + if {![gdb_simple_compile $me $src executable $compile_flags]} { + # Try again, but with a raw hex instruction so we don't rely on + # assembler support for SME. + + set compile_flags "{additional_flags=-march=armv8-a}" + + # Compile a test program containing SME instructions. + set src { + int main() { + asm volatile (".word 0xD503457F"); + return 0; + } + } + + if {![gdb_simple_compile $me $src executable $compile_flags]} { + return 0 + } + } + + # Compilation succeeded so now run it via gdb. + clean_restart $obj + gdb_run_cmd + gdb_expect { + -re ".*Illegal instruction.*${gdb_prompt} $" { + verbose -log "\n$me sme support not detected" + set allow_sme_tests 0 + } + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" { + verbose -log "\n$me: sme support detected" + set allow_sme_tests 1 + } + default { + warning "\n$me: default case taken" + set allow_sme_tests 0 + } + } + gdb_exit + remote_file build delete $obj + + # While testing for SME support, also discover all the supported vector + # length values. + aarch64_initialize_sme_information + + verbose "$me: returning $allow_sme_tests" 2 + return $allow_sme_tests +} + +# Assuming SME is supported by the target, run some checks to determine all +# the supported streaming vector length values and return an array containing +# all of those values. Since this is a gdb_caching_proc, this proc will only +# be executed once. +# +# To check if a particular SME streaming vector length is supported, the +# following code can be used. For instance, for svl == 32: +# +# if {[aarch64_supports_sme_svl 32]} { +# verbose -log "SME streaming vector length 32 is supported." +# } +# +# This procedure should NEVER be called by hand, as it reinitializes the GDB +# session and will derail a test. This should be called automatically as part +# of the SME support test routine allow_aarch64_sme_tests. Users should +# restrict themselves to calling the helper proc aarch64_supports_sme_svl. + +gdb_caching_proc aarch64_initialize_sme_information { } { + global srcdir + + set src "${srcdir}/lib/aarch64-test-sme.c" + set test_exec [standard_temp_file "aarch64-test-sme.x"] + set compile_flags "{additional_flags=-march=armv8-a+sme}" + array set supported_svl {} + + # Compile the SME vector length test. + set result [gdb_compile $src $test_exec executable [list debug ${compile_flags} nowarnings]] + + if {$result != ""} { + verbose -log "Failed to compile SME information gathering test." + return [array get supported_svl] + } + + clean_restart $test_exec + + if {![runto_main]} { + return [array get supported_svl] + } + + set stop_breakpoint "stop here" + gdb_breakpoint [gdb_get_line_number $stop_breakpoint $src] + gdb_continue_to_breakpoint $stop_breakpoint + + # Go through the data and extract the supported SME vector lengths. + set svl_count [get_valueof "" "supported_svl_count" "0" \ + "fetch value of supported_svl_count"] + verbose -log "Found $svl_count supported SME vector length values" + + for {set svl_index 0} {$svl_index < $svl_count} {incr svl_index} { + set test_svl [get_valueof "" "supported_svl\[$svl_index\]" "0" \ + "fetch value of supported_svl\[$svl_index\]"] + + # Mark this streaming vector length as supported. + if {$test_svl != 0} { + verbose -log "Found supported SME vector length $test_svl" + set supported_svl($test_svl) 1 + } + } + + gdb_exit + verbose -log "Cleaning up" + remote_file build delete $test_exec + + verbose -log "Done gathering information about AArch64 SME vector lengths." + + # Return the array containing all of the supported SME svl values. + return [array get supported_svl] +} + +# +# Return 1 if the target supports SME svl LENGTH +# Return 0 otherwise. +# + +proc aarch64_supports_sme_svl { length } { + + # Fetch the cached array of supported SME svl values. + array set supported_svl [aarch64_initialize_sme_information] + + # Do we have the global values cached? + if {![info exists supported_svl($length)]} { + verbose -log "Target does not support SME svl $length" + return 0 + } + + # The target supports SME svl LENGTH. + return 1 +} # A helper that compiles a test case to see if __int128 is supported. proc gdb_int128_helper {lang} {