From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 4XdVFs4kDmnrvykAWB0awg (envelope-from ) for ; Fri, 07 Nov 2025 11:56:46 -0500 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=syntacore.com header.i=@syntacore.com header.a=rsa-sha256 header.s=m header.b=SBdbjnQk; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 543FF1E0BC; Fri, 07 Nov 2025 11:56:46 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 2FA001E04C for ; Fri, 07 Nov 2025 11:56:43 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CFB7E3858C74 for ; Fri, 7 Nov 2025 16:56:42 +0000 (GMT) Received: from m.syntacore.com (m.syntacore.com [178.249.69.228]) by sourceware.org (Postfix) with ESMTPS id 5AB233858C55 for ; Fri, 7 Nov 2025 16:55:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5AB233858C55 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=syntacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=syntacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5AB233858C55 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=178.249.69.228 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1762534551; cv=none; b=CfFw++D1lyQqjqPtsVSBeE3rgGW33+noAfeQPzEWGVjDV4RKtJX/CcG9X6OyXFVthDS9JfRiWpGgOXZTWHk7XVzMAwYBHOXdoi8b6mmrEQbpw3zoyiw/W/Om4IAKxjGZQimrRpoJc4SXAFsAgXvAWB2Pcc2hApGj8f7dO9V5TgU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1762534551; c=relaxed/simple; bh=g0H38Ks0BHEImSIWUn87te7v9lQ1W5Rxccnsp2SHo4k=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=rsc4EbCRYd+P5R3VZS21LhEJarr8VadoTiHKMVnE72tu4uNa6tF062UHYudQX8q+sHIC6Dclesr81Emwi0jEXcgzF2f7GbGjEAco0oxBYkSv2imX6f0NTvGcDyKtvpsRcFCuuaypeoRfv/+mSVqFG52mOdW/SDR2S+8uRpkGhHU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5AB233858C55 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=syntacore.com header.i=@syntacore.com header.a=rsa-sha256 header.s=m header.b=SBdbjnQk Received: from MRN-SC-KSMG-01.corp.syntacore.com (localhost [127.0.0.1]) by m.syntacore.com (Postfix) with ESMTP id 5DE051A0005 for ; Fri, 7 Nov 2025 16:55:50 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 m.syntacore.com 5DE051A0005 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=syntacore.com; s=m; t=1762534550; bh=jHEGgUqCIcpoMCI+nYFE5fG1QrY+H1GzN2Ff04ikbaw=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=SBdbjnQkPrtvyXtt0lZMlknDyeGrRTcGBHWZRWe0bow4O5UO8ErYtYvnSJNEVsoJK YSCXELOTEmo++BbifjFstweGJ3WZjRXOa5x22WFsNHj5Ic2Ubz9gFAKEGPC/yUnjA/ ihNg9l+p9K3xUHhoExJdYgeUJiSffByRVBlcLs0aor9bW0mUW8jdSF+kBnaGC/C9QW Dr7FsjSr/QaEDM+xRPLkikNBNpKP7ygn2v0RzROhhK0U7bGjJqpAoVEFTHdvPO4ZE8 yhH/8jVVy3gMCJ707QEZt22WJXkds+cXBBsrxAFIwfJnXguwXexjVhhs2aHCOHqveZ BkStdnp76Xqiw== Received: from S-SC-EXCH-01.corp.syntacore.com (mail.syntacore.com [10.76.202.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by m.syntacore.com (Postfix) with ESMTPS for ; Fri, 7 Nov 2025 16:55:50 +0000 (UTC) Received: from ouran.high.school.host.club (10.178.157.72) by S-SC-EXCH-01.corp.syntacore.com (10.76.202.20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.29; Fri, 7 Nov 2025 19:55:46 +0300 From: Kirill Radkin To: CC: Kirill Radkin Subject: [PATCH 2/2] RISC-V Vector Extension Support Testing Date: Fri, 7 Nov 2025 19:55:34 +0300 Message-ID: <20251107165534.1688124-2-kirill.radkin@syntacore.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251107165534.1688124-1-kirill.radkin@syntacore.com> References: <20251107165534.1688124-1-kirill.radkin@syntacore.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.178.157.72] X-ClientProxiedBy: S-SC-EXCH-01.corp.syntacore.com (10.76.202.20) To S-SC-EXCH-01.corp.syntacore.com (10.76.202.20) X-KSMG-AntiPhishing: not scanned, disabled by settings X-KSMG-AntiSpam-Interceptor-Info: not scanned X-KSMG-AntiSpam-Status: not scanned, disabled by settings X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.1.1.8310, bases: 2025/11/07 15:09:00 #27893311 X-KSMG-AntiVirus-Status: NotDetected, skipped X-KSMG-LinksScanning: NotDetected, bases: 2025/11/07 16:09:00 X-KSMG-Message-Action: skipped X-KSMG-Rule-ID: 5 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: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org This patch add extensive testing for RISC-V Vector Extension Support. --- ...iscv-vector-abi-full-generate-template.txt | 153 ++++++++ .../riscv-vector-abi-full-generate.py | 360 ++++++++++++++++++ .../gdb.arch/riscv-vector-abi-full.c | 23 ++ .../gdb.arch/riscv-vector-abi-full.exp | 65 ++++ gdb/testsuite/gdb.arch/riscv-vector-abi.c | 157 ++++++++ gdb/testsuite/gdb.arch/riscv-vector-abi.exp | 230 +++++++++++ .../gdb.arch/riscv-vu-availability.c | 67 ++++ .../gdb.arch/riscv-vu-availability.exp | 72 ++++ .../gdb.arch/riscv-vu-consitency-checks.c | 79 ++++ .../gdb.arch/riscv-vu-consitency-checks.exp | 152 ++++++++ gdb/testsuite/gdb.arch/riscv-vu-ctx-print.c | 106 ++++++ gdb/testsuite/gdb.arch/riscv-vu-ctx-print.exp | 107 ++++++ gdb/testsuite/gdb.arch/riscv-vu-printout.c | 69 ++++ gdb/testsuite/gdb.arch/riscv-vu-printout.exp | 92 +++++ .../gdb.arch/riscv-vu-rvv-unsupported.c | 23 ++ .../gdb.arch/riscv-vu-rvv-unsupported.exp | 46 +++ gdb/testsuite/gdb.arch/riscv-vu-rwr.c | 62 +++ gdb/testsuite/gdb.arch/riscv-vu-rwr.exp | 163 ++++++++ .../gdb.arch/riscv-vu-side-effects.c | 86 +++++ .../gdb.arch/riscv-vu-side-effects.exp | 162 ++++++++ gdb/testsuite/lib/riscv64-rvv-lib.exp | 166 ++++++++ 21 files changed, 2440 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/riscv-vector-abi-full-generate-template.txt create mode 100644 gdb/testsuite/gdb.arch/riscv-vector-abi-full-generate.py create mode 100644 gdb/testsuite/gdb.arch/riscv-vector-abi-full.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vector-abi-full.exp create mode 100644 gdb/testsuite/gdb.arch/riscv-vector-abi.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vector-abi.exp create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-availability.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-availability.exp create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-consitency-checks.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-consitency-checks.exp create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-ctx-print.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-ctx-print.exp create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-printout.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-printout.exp create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-rvv-unsupported.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-rvv-unsupported.exp create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-rwr.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-rwr.exp create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-side-effects.c create mode 100644 gdb/testsuite/gdb.arch/riscv-vu-side-effects.exp create mode 100644 gdb/testsuite/lib/riscv64-rvv-lib.exp diff --git a/gdb/testsuite/gdb.arch/riscv-vector-abi-full-generate-template.txt b/gdb/testsuite/gdb.arch/riscv-vector-abi-full-generate-template.txt new file mode 100644 index 00000000000..081572bd8ea --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vector-abi-full-generate-template.txt @@ -0,0 +1,153 @@ +{% macro main_header(file) -%} +/* DO NOT EDIT: Autogenerated by {{ file }} + Copyright 2025 Free Software Foundation, Inc. + This file is part of GDB, the GNU debugger. */ + +#include +{% endmacro %} + +{% macro main_tail_start() %} +void +test () +{ + size_t vl = 0; +{% endmacro %} + +{% macro expect_header(file) -%} +# DO NOT EDIT: Autogenerated by {{ file }} +# Copyright 2025 Free Software Foundation, Inc. +# This file is part of GDB, the GNU debugger. + +proc generate_response { start step count } { + if {$step == 0 && $count > 8} { + return "\\{${start} \\}" + } + + set res "\\{$start" + set count [expr {$count - 1}] + + for {set i 0} {$i < $count} {incr i} { + set start [expr {$start + $step}] + set res "${res}, $start" + } + set res "${res}\\}" + return $res +} + +proc generate_tuple_response { nfields starts step count } { + set res "\\{__val = \\{" + set start [lindex $starts 0] + set entry [generate_response $start $step $count] + set res "${res}${entry}" + + for {set i 1} {$i < $nfields} {incr i} { + set start [lindex $starts $i] + set entry [generate_response $start $step $count] + set res "${res}, $entry" + } + + set res "${res}\\}\\}" + return $res +} + +standard_testfile [standard_output_file riscv-vector-abi-full-generated.c] + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 +} + +if {![runto_main]} { + return -1 +} +{% endmacro %} + +{% macro func_name_template(type_name) -%} +add_{{ type_name }} +{%- endmacro %} + +{% macro func_template(type_name, vadd_name, func_name, vsetvlmax) -%} +{{ type_name }} +{{ func_name }} ({{ type_name }} a, {{ type_name }} b) +{ + size_t vl = {{ vsetvlmax }} (); + return {{ vadd_name }} (a, b, vl); +} + +{% endmacro %} + +{% macro main_entry_template(type_name, var_idx, vmv_name, var_val, func_name, vsetvlmax) %} + // {{ type_name }} + vl = {{ vsetvlmax }} (); + {{ type_name }} var{{ var_idx }} = {{ vmv_name }} ({{ var_val }}, vl); + {{ type_name }} res{{ var_idx }} = {{ func_name }} (var{{ var_idx }}, var{{ var_idx }}); + // {{ type_name }}_break +{% endmacro %} + +{% macro test_entry_template(main_file, type_name, break_idx, var_idx, var_val, res_val, func_name) %} +gdb_breakpoint "[host_standard_output_file {{ main_file }}]:[gdb_get_line_number "{{ type_name }}_break"]" +gdb_continue_to_breakpoint "break {{ break_idx }}" +set vl [get_valueof "/d" "vl" -1 "get_vl_{{ break_idx }}"] +gdb_test "print var{{ var_idx }}" "[generate_response {{ var_val }} 0 $vl]" +gdb_test "print res{{ var_idx }}" "[generate_response {{ res_val }} 0 $vl]" +gdb_test "print {{ func_name }} (var{{ var_idx }}, var{{ var_idx }})" "[generate_response {{ res_val }} 0 $vl]" +{% endmacro %} + +{% macro tuple_func_template_start() %} +{type_name} +{func_name} ({type_name} a, {type_name} b) +{{ '{{' }} + {type_name} result; + size_t vl = {vsetvlmax} (); +{% endmacro %} + +{% macro tuple_func_template_entry(index) %} + {short_type_name} a{{ index }} = {vget_name} (a, {{ index }}); + {short_type_name} b{{ index }} = {vget_name} (b, {{ index }}); + {short_type_name} r{{ index }} = {vadd_name} (a{{ index }}, b{{ index }}, vl); + result = {vset_name} (result, {{ index }}, r{{ index }}); +{% endmacro %} + +{% macro tuple_func_template_end() %} + return result; +{{ '}}' }} +{% endmacro %} + +{% macro tuple_main_entry_template_start() %} + // {type_name} + vl = {vsetvlmax} (); + {type_name} var{var_idx}; +{% endmacro %} + +{% macro tuple_main_entry_template_entry(index) %} + {short_type_name} var{var_idx}_{{ index }} = {vmv_name} ({var_values[{{ index }}]}, vl); + var{var_idx} = {vset_name} (var{var_idx}, {{ index }}, var{var_idx}_{{ index }}); +{% endmacro %} + +{% macro tuple_main_entry_template_end() %} + {type_name} res{var_idx} = {func_name} (var{var_idx}, var{var_idx}); + // {type_name}_break +{% endmacro %} + +{% macro tuple_test_template_start(main_file) %} +gdb_breakpoint "[host_standard_output_file {{ main_file }}]:[gdb_get_line_number "{type_name}_break"]" +gdb_continue_to_breakpoint "break {break_idx}" +set vl [get_valueof "/d" "vl" -1 "get_vl_{break_idx}"] +{% endmacro %} + +{% macro tuple_test_template_entry_first(index) -%} +gdb_test "print var{var_idx}_{{ index }}" "[generate_response {var_values[{{ index }}]} 0 $vl]" +{% endmacro %} + +{% macro tuple_test_template_entry_middle() -%} +set res_values {{ '{{' }} +{%- endmacro %} + +{% macro tuple_test_template_entry_second(index) -%} +{{ ' ' }}{{ '{{' }}{res_values[{{ index }}]}{{ '}}' }} +{%- endmacro %} + +{% macro tuple_test_template_end(nfields) -%} +{{ ' }}' }} +gdb_test "print res{var_idx}" "[generate_tuple_response {{ nfields }} $res_values 0 $vl]" +gdb_test "print {func_name} (var{var_idx}, var{var_idx})" "[generate_tuple_response {{ nfields }} $res_values 0 $vl]" +{% endmacro %} diff --git a/gdb/testsuite/gdb.arch/riscv-vector-abi-full-generate.py b/gdb/testsuite/gdb.arch/riscv-vector-abi-full-generate.py new file mode 100644 index 00000000000..b9113d526df --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vector-abi-full-generate.py @@ -0,0 +1,360 @@ +import os +import itertools +import re +from pathlib import Path +from enum import StrEnum +from jinja2 import Environment, FileSystemLoader + +FILE = Path(__file__).name +TEST_DIR = Path(__file__).resolve().parent +JINJA_TEMPLATE_FILE = "riscv-vector-abi-full-generate-template.txt" + +WORK_DIR = os.getenv("WORK_DIR") +TEST_NAME = os.getenv("TEST_NAME") + + +class ElemType(StrEnum): + INT = "int" + UINT = "uint" + FLOAT = "float" + + +class InstrType(StrEnum): + VADD = "vadd" + VMV = "vmv" + VGET = "vget" + VSET = "vset" + VSETVLMAX = "vlmax" + + +class InstructionTemplate: + vadd_instr_templates = { + ElemType.INT: "__riscv_vadd_vv_i{suffix1}", + ElemType.UINT: "__riscv_vadd_vv_u{suffix1}", + ElemType.FLOAT: "__riscv_vfadd_vv_f{suffix1}", + } + + vmv_instr_templates = { + ElemType.INT: "__riscv_vmv_v_x_i{suffix1}", + ElemType.UINT: "__riscv_vmv_v_x_u{suffix1}", + ElemType.FLOAT: "__riscv_vfmv_v_f_f{suffix1}", + } + + vget_instr_templates = { + ElemType.INT: "__riscv_vget_v_i{suffix1}_i{suffix2}", + ElemType.UINT: "__riscv_vget_v_u{suffix1}_u{suffix2}", + ElemType.FLOAT: "__riscv_vget_v_f{suffix1}_f{suffix2}", + } + + vset_instr_templates = { + ElemType.INT: "__riscv_vset_v_i{suffix1}_i{suffix2}", + ElemType.UINT: "__riscv_vset_v_u{suffix1}_u{suffix2}", + ElemType.FLOAT: "__riscv_vset_v_f{suffix1}_f{suffix2}", + } + + vsetvlmax_template = {k: "__riscv_vsetvlmax_e{suffix1}" for k in ElemType} + + templates = { + InstrType.VADD: vadd_instr_templates, + InstrType.VMV: vmv_instr_templates, + InstrType.VGET: vget_instr_templates, + InstrType.VSET: vset_instr_templates, + InstrType.VSETVLMAX: vsetvlmax_template, + } + + def get(self, elem_type: ElemType, instr_type: InstrType): + return self.templates[instr_type][elem_type] + + +def generate(directory: Path, test_name: Path): + instr_templates = InstructionTemplate() + + env = Environment(loader=FileSystemLoader(str(TEST_DIR))) + tpl = env.get_template(str(JINJA_TEMPLATE_FILE)) + + counter_vars = itertools.count(0) + counter_values = itertools.cycle(range(0, 64, 1)) + counter_break_idx = itertools.count(2) + + main_file = Path(f"{test_name}.c") + main_file_path = directory / main_file + + test_script = Path(f"{test_name}.exp") + test_script_path = directory / test_script + + if not os.path.exists(main_file_path): + os.mknod(main_file_path) + + if not os.path.exists(test_script_path): + os.mknod(test_script_path) + + main_header = tpl.module.main_header(FILE) + + with open(main_file_path, "w") as f: + f.write(main_header) + + main_tail = tpl.module.main_tail_start() + + expect_header = tpl.module.expect_header(FILE) + + with open(test_script_path, "w") as f: + f.write(expect_header) + + # int, uint, float + + # fmt: off + vint_types = [ + # 8-bit + "vint8mf8_t", "vint8mf4_t", "vint8mf2_t", "vint8m1_t", "vint8m2_t", "vint8m4_t", "vint8m8_t", + + # 16-bit + "vint16mf4_t", "vint16mf2_t", "vint16m1_t", "vint16m2_t", "vint16m4_t", "vint16m8_t", + + # 32-bit + "vint32mf2_t", "vint32m1_t", "vint32m2_t", "vint32m4_t", "vint32m8_t", + + # 64-bit + "vint64m1_t", "vint64m2_t", "vint64m4_t", "vint64m8_t", + ] + + vuint_types = [_.replace("int", "uint") for _ in vint_types] + + vfloat_types = [ + # SEW = 16 (half-precision) + "vfloat16mf4_t", "vfloat16mf2_t", "vfloat16m1_t", "vfloat16m2_t", "vfloat16m4_t", "vfloat16m8_t", + + # SEW = 32 (single-precision) + "vfloat32mf2_t", "vfloat32m1_t", "vfloat32m2_t", "vfloat32m4_t", "vfloat32m8_t", + + # SEW = 64 (double-precision) + "vfloat64m1_t", "vfloat64m2_t", "vfloat64m4_t", "vfloat64m8_t", + ] + # fmt: on + + for type_name in vint_types + vuint_types + vfloat_types: + m = re.match(r"v(int|uint|float)(8|16|32|64)(m|mf)(1|2|4|8)_t", type_name) + if not m: + raise RuntimeError("wrong type") + + elem_type = ElemType(m.group(1)) + small_suffix = "".join(m.group(2, 3, 4)) # 16m2 + + func_name = tpl.module.func_name_template(type_name) + vsetvlmax = instr_templates.get(elem_type, InstrType.VSETVLMAX).format( + suffix1=small_suffix + ) + vadd_name = instr_templates.get(elem_type, InstrType.VADD).format( + suffix1=small_suffix + ) + vmv_name = instr_templates.get(elem_type, InstrType.VMV).format( + suffix1=small_suffix + ) + + var_idx = next(counter_vars) + var_val = next(counter_values) + res_val = 2 * var_val + + new_line = tpl.module.func_template( + type_name, + vadd_name, + func_name, + vsetvlmax, + ) + + with open(main_file_path, "a") as f: + f.write(new_line) + + main_tail += tpl.module.main_entry_template( + type_name, + var_idx, + vmv_name, + var_val, + func_name, + vsetvlmax, + ) + + break_idx = next(counter_break_idx) + test_command = tpl.module.test_entry_template( + main_file, + type_name, + break_idx, + var_idx, + var_val, + res_val, + func_name, + ) + with open(test_script_path, "a") as f: + f.write(test_command) + + # tuple int + + # fmt: off + vint_tuple_types = [ + # LMUL = mf8 + "vint8mf8x2_t", "vint8mf8x3_t", "vint8mf8x4_t", "vint8mf8x5_t", "vint8mf8x6_t", "vint8mf8x7_t", "vint8mf8x8_t", + + # LMUL = mf4 + "vint8mf4x2_t", "vint8mf4x3_t", "vint8mf4x4_t", "vint8mf4x5_t", "vint8mf4x6_t", "vint8mf4x7_t", "vint8mf4x8_t", + "vint16mf4x2_t", "vint16mf4x3_t", "vint16mf4x4_t", "vint16mf4x5_t", "vint16mf4x6_t", "vint16mf4x7_t", "vint16mf4x8_t", + + # LMUL = mf2 + "vint8mf2x2_t", "vint8mf2x3_t", "vint8mf2x4_t", "vint8mf2x5_t", "vint8mf2x6_t", "vint8mf2x7_t", "vint8mf2x8_t", + "vint16mf2x2_t", "vint16mf2x3_t", "vint16mf2x4_t", "vint16mf2x5_t", "vint16mf2x6_t", "vint16mf2x7_t", "vint16mf2x8_t", + "vint32mf2x2_t", "vint32mf2x3_t", "vint32mf2x4_t", "vint32mf2x5_t", "vint32mf2x6_t", "vint32mf2x7_t", "vint32mf2x8_t", + + # LMUL = m1 + "vint8m1x2_t", "vint8m1x3_t", "vint8m1x4_t", "vint8m1x5_t", "vint8m1x6_t", "vint8m1x7_t", "vint8m1x8_t", + "vint16m1x2_t", "vint16m1x3_t", "vint16m1x4_t", "vint16m1x5_t", "vint16m1x6_t", "vint16m1x7_t", "vint16m1x8_t", + "vint32m1x2_t", "vint32m1x3_t", "vint32m1x4_t", "vint32m1x5_t", "vint32m1x6_t", "vint32m1x7_t", "vint32m1x8_t", + "vint64m1x2_t", "vint64m1x3_t", "vint64m1x4_t", "vint64m1x5_t", "vint64m1x6_t", "vint64m1x7_t", "vint64m1x8_t", + + # LMUL = m2 + "vint8m2x2_t", "vint8m2x3_t", "vint8m2x4_t", + "vint16m2x2_t", "vint16m2x3_t", "vint16m2x4_t", + "vint32m2x2_t", "vint32m2x3_t", "vint32m2x4_t", + "vint64m2x2_t", "vint64m2x3_t", "vint64m2x4_t", + + # LMUL = m4 + "vint8m4x2_t", + "vint16m4x2_t", + "vint32m4x2_t", + "vint64m4x2_t", + ] + + vuint_tuple_types = [_.replace("int", "uint") for _ in vint_tuple_types] + + vfloat_tuple_types = [ + # vfloat16 + "vfloat16mf4x2_t", "vfloat16mf4x3_t", "vfloat16mf4x4_t", "vfloat16mf4x5_t", + "vfloat16mf4x6_t", "vfloat16mf4x7_t", "vfloat16mf4x8_t", + "vfloat16mf2x2_t", "vfloat16mf2x3_t", "vfloat16mf2x4_t", "vfloat16mf2x5_t", + "vfloat16mf2x6_t", "vfloat16mf2x7_t", "vfloat16mf2x8_t", + "vfloat16m1x2_t", "vfloat16m1x3_t", "vfloat16m1x4_t", "vfloat16m1x5_t", + "vfloat16m1x6_t", "vfloat16m1x7_t", "vfloat16m1x8_t", + "vfloat16m2x2_t", "vfloat16m2x3_t", "vfloat16m2x4_t", + "vfloat16m4x2_t", + + # LMUL = mf2 (1/2) + "vfloat32mf2x2_t", "vfloat32mf2x3_t", "vfloat32mf2x4_t", "vfloat32mf2x5_t", + "vfloat32mf2x6_t", "vfloat32mf2x7_t", "vfloat32mf2x8_t", + + # LMUL = m1 (1) + "vfloat32m1x2_t", "vfloat32m1x3_t", "vfloat32m1x4_t", "vfloat32m1x5_t", + "vfloat32m1x6_t", "vfloat32m1x7_t", "vfloat32m1x8_t", + "vfloat64m1x2_t", "vfloat64m1x3_t", "vfloat64m1x4_t", "vfloat64m1x5_t", + "vfloat64m1x6_t", "vfloat64m1x7_t", "vfloat64m1x8_t", + + # LMUL = m2 (2) + "vfloat32m2x2_t", "vfloat32m2x3_t", "vfloat32m2x4_t", + "vfloat64m2x2_t", "vfloat64m2x3_t", "vfloat64m2x4_t", + + # LMUL = m4 (4) + "vfloat32m4x2_t", + "vfloat64m4x2_t", + ] + # fmt: on + + def get_tuple_template(nfields: int) -> str: + tuple_template = tpl.module.tuple_func_template_start() + for i in range(nfields): + tuple_template += tpl.module.tuple_func_template_entry(i) + tuple_template += tpl.module.tuple_func_template_end() + return tuple_template + + def get_main_tuple_template(nfields: int) -> str: + main_tuple_template = tpl.module.tuple_main_entry_template_start() + for i in range(nfields): + main_tuple_template += tpl.module.tuple_main_entry_template_entry(i) + main_tuple_template += tpl.module.tuple_main_entry_template_end() + return main_tuple_template + + def get_test_tuple_template(nfields: int) -> str: + test_tuple_template = tpl.module.tuple_test_template_start(main_file) + for i in range(nfields): + test_tuple_template += tpl.module.tuple_test_template_entry_first(i) + test_tuple_template += tpl.module.tuple_test_template_entry_middle() + for i in range(nfields): + test_tuple_template += tpl.module.tuple_test_template_entry_second(i) + test_tuple_template += tpl.module.tuple_test_template_end(nfields) + return test_tuple_template + + for type_name in vint_tuple_types + vuint_tuple_types + vfloat_tuple_types: + m = re.match( + r"v(int|uint|float)(8|16|32|64)(m|mf)(1|2|4|8)(x)([2-8])_t", + type_name, + ) + if not m: + raise RuntimeError("wrong type") + + elem_type = ElemType(m.group(1)) + nfields = int(m.group(6)) + short = type_name[:-4] + "_t" + big_suffix = "".join(m.group(2, 3, 4, 5, 6)) # 16m2x3 + small_suffix = "".join(m.group(2, 3, 4)) # 16m2 + + func_name = tpl.module.func_name_template(type_name) + vsetvlmax = instr_templates.get(elem_type, InstrType.VSETVLMAX).format( + suffix1=small_suffix + ) + vget_name = instr_templates.get(elem_type, InstrType.VGET).format( + suffix1=big_suffix, suffix2=small_suffix + ) + vadd_name = instr_templates.get(elem_type, InstrType.VADD).format( + suffix1=small_suffix + ) + vset_name = instr_templates.get(elem_type, InstrType.VSET).format( + suffix1=small_suffix, suffix2=big_suffix + ) + vmv_name = instr_templates.get(elem_type, InstrType.VMV).format( + suffix1=small_suffix + ) + + var_idx = next(counter_vars) + var_values = [val for _, val in zip(range(nfields), counter_values)] + res_values = [2 * val for val in var_values] + + string = get_tuple_template(nfields).format( + type_name=type_name, + short_type_name=short, + vget_name=vget_name, + vadd_name=vadd_name, + vset_name=vset_name, + func_name=func_name, + vsetvlmax=vsetvlmax, + ) + + with open(main_file_path, "a") as f: + f.write(string) + + main_tail += get_main_tuple_template(nfields).format( + vsetvlmax=vsetvlmax, + short_type_name=short, + var_idx=var_idx, + small_suffix=small_suffix, + type_name=type_name, + vset_name=vset_name, + func_name=func_name, + vmv_name=vmv_name, + var_values=var_values, + ) + + break_idx = next(counter_break_idx) + test_command = get_test_tuple_template(nfields).format( + type_name=type_name, + break_idx=break_idx, + var_idx=var_idx, + var_values=var_values, + res_values=res_values, + func_name=func_name, + ) + + with open(test_script_path, "a") as f: + f.write(test_command) + + with open(main_file_path, "a") as f: + f.write(main_tail) + f.write("\n return;\n}\n") + f.write("\nint main () {test();}\n") + + +generate(WORK_DIR, TEST_NAME) diff --git a/gdb/testsuite/gdb.arch/riscv-vector-abi-full.c b/gdb/testsuite/gdb.arch/riscv-vector-abi-full.c new file mode 100644 index 00000000000..b8ab1fc1784 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vector-abi-full.c @@ -0,0 +1,23 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +int +main () +{ + __asm__ __volatile__ ("vsetvli t0, x0, e8"); + return 0; /* break 2 */ +} diff --git a/gdb/testsuite/gdb.arch/riscv-vector-abi-full.exp b/gdb/testsuite/gdb.arch/riscv-vector-abi-full.exp new file mode 100644 index 00000000000..3ee6c7edc15 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vector-abi-full.exp @@ -0,0 +1,65 @@ +# Copyright 2025 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 . + +load_lib riscv64-rvv-lib.exp + +if {[catch {exec python3 -c "import jinja2"} result]} { + unsupported "python3 with jinja2 is required" + return +} + +if {![riscv_support_rvv]} { + unsupported "RVV unsupported" + return +} + +if {![riscv_support_rvv_intrinsic]} { + unsupported "RVV intrinsic unsupported" + return +} + +standard_testfile + +set compile_flags {"debug"} +lappend compile_flags "additional_flags=-march=rv64gcv" + +# First, we figure out VLENB value to set correct vector extension to march +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +gdb_breakpoint "$srcfile:[gdb_get_line_number "break 2"]" +gdb_continue_to_breakpoint "preparing stage" +set vlenb [riscvlib_rvv_get_csr vlenb "$testfile"] + +set compile_flags {"debug"} +if {$vlenb >= 16} { + lappend compile_flags "additional_flags=-march=rv64gcv_zvfh" +} elseif {$vlenb >= 8} { + lappend compile_flags "additional_flags=-march=rv64gc_zve64d_zvfh" +} else { + unsupported "Unsupported VLENB value: $vlenb" + return +} + +set env(WORK_DIR) [standard_output_file ""] +set env(TEST_NAME) riscv-vector-abi-full-generated +exec python3 $srcdir/$subdir/riscv-vector-abi-full-generate.py + +source [standard_output_file riscv-vector-abi-full-generated.exp] diff --git a/gdb/testsuite/gdb.arch/riscv-vector-abi.c b/gdb/testsuite/gdb.arch/riscv-vector-abi.c new file mode 100644 index 00000000000..120e2e2fd1e --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vector-abi.c @@ -0,0 +1,157 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +#include +#include + +unsigned +do_vlen_read () +{ + unsigned vlenb; + asm volatile ("csrr %[vlenb], vlenb" : [vlenb] "=r"(vlenb) : :); + /* According to vector spec: "vlenb holds the value VLEN/8". */ + return vlenb * 8; +} + +vint64m1_t +foo (vint64m1_t a, vint32mf2_t b, vint64m1_t c, size_t n) +{ + vint64m1_t tmp = __riscv_vwadd_wv_i64m1 (a, b, n); + return __riscv_vadd_vv_i64m1 (c, tmp, n); +} + +vint32m4_t +foo1 (vint32m4_t a, vint16m2_t b, size_t n) +{ + return __riscv_vwadd_wv_i32m4 (a, b, n); +} + +vint32m4_t +foo2 (vint16m2_t a, vint32m4_t b, size_t n) +{ + return __riscv_vwadd_wv_i32m4 (b, a, n); +} + +vint64m8_t +foo3 (vint64m8_t a, vint64m8_t b, vint64m8_t c, size_t n) +{ + vint64m8_t tmp = __riscv_vadd_vv_i64m8 (a, b, n); + return __riscv_vadd_vv_i64m8 (tmp, c, n); +} + +vint64m8_t +foo4 (vint64m8_t a, vint64m8_t b, vbool8_t mask, vbool8_t mask2, size_t n) +{ + return __riscv_vadd_vv_i64m8_m (mask2, a, b, n); +} + +vint32m4_t +foo5_get0 (vint16m2_t tmp_a, vint32m4x2_t a) +{ + return __riscv_vget_v_i32m4x2_i32m4 (a, 0); +} + +vint32m4_t +foo5_get1 (vint16m2_t tmp_a, vint32m4x2_t a) +{ + return __riscv_vget_v_i32m4x2_i32m4 (a, 1); +} + +vint32mf2_t +foo6_get0 (vint16m2_t tmp_a, vint32mf2x2_t a) +{ + return __riscv_vget_v_i32mf2x2_i32mf2 (a, 0); +} + +vint32mf2_t +foo6_get1 (vint16m2_t tmp_a, vint32mf2x2_t a) +{ + return __riscv_vget_v_i32mf2x2_i32mf2 (a, 1); +} + +int +main () +{ + unsigned n = do_vlen_read () / 64; + vint64m1_t a = __riscv_vmv_v_x_i64m1 (42, n); + vint32mf2_t b = __riscv_vmv_v_x_i32mf2 (43, n); + vint64m1_t c = __riscv_vmv_v_x_i64m1 (44, n); + + vint64m1_t res = foo (a, b, c, n); + /* break 2 */ + + n = do_vlen_read () * 4 / 32; + vint32m4_t g = __riscv_vmv_v_x_i32m4 (48, n); + vint16m2_t h = __riscv_vmv_v_x_i16m2 (49, n); + + vint32m4_t res_1 = foo1 (g, h, n); // g is on v8-v11, h is on v12-v13 + vint32m4_t res_2 = foo2 (h, g, n); // h is on v8-v9, g is on v12-v15 + /* break 3 */ + + n = do_vlen_read () * 8 / 64; + vint64m8_t big1 = __riscv_vmv_v_x_i64m8 (50, n); + vint64m8_t big2 = __riscv_vmv_v_x_i64m8 (51, n); + vint64m8_t big3 = __riscv_vmv_v_x_i64m8 (52, n); + vint64m8_t big_res = foo3 (big1, big2, big3, n); + /* break 4 */ + + unsigned mask_size = n / 8; + uint8_t *rs1_mask = malloc (mask_size * sizeof (uint8_t)); + for (int i = 0; i < mask_size; i++) + rs1_mask[i] = 0xa5; + + vbool8_t mask = __riscv_vlm_v_b8 (rs1_mask, n); + vint64m8_t masked_sum = foo4 (big1, big2, mask, mask, n); + /* break 5 */ + + n = do_vlen_read () * 4 * 2 / 32; + unsigned addr_size = n / 2; + uint32_t *addr = malloc (addr_size * sizeof (uint32_t)); + for (unsigned i = 0; i < addr_size; i++) + addr[i] = 8 * (uint32_t)i; + + vuint32m4_t rs2 = __riscv_vle32_v_u32m4 (addr, addr_size); + /* break 6 */ + + int32_t *rs1 = malloc (n); + for (int i = 0; i < n; i++) + rs1[i] = (int32_t)i; + + vint32m4x2_t a_seg = __riscv_vluxseg2ei32_v_i32m4x2 (rs1, rs2, n); + /* break 7 */ + vint32m4_t res_a_seg0 = foo5_get0 (h, a_seg); + /* break 8 */ + vint32m4_t res_a_seg1 = foo5_get1 (h, a_seg); + /* break 9 */ + + vuint32mf2_t rs2_2 = __riscv_vle32_v_u32mf2 (addr, addr_size); + /* break 10 */ + + n = do_vlen_read () / 32; + vint32mf2x2_t b_seg = __riscv_vluxseg2ei32_v_i32mf2x2 (rs1, rs2_2, n); + /* break 11 */ + vint32mf2_t res_b_seg0 = foo6_get0 (h, b_seg); + /* break 12 */ + vint32mf2_t res_b_seg1 = foo6_get1 (h, b_seg); + /* break 13 */ + + free (rs1_mask); + free (addr); + free (rs1); + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/riscv-vector-abi.exp b/gdb/testsuite/gdb.arch/riscv-vector-abi.exp new file mode 100644 index 00000000000..00b046f2f1f --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vector-abi.exp @@ -0,0 +1,230 @@ +# Copyright 2025 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 . + +load_lib riscv64-rvv-lib.exp + +set get_vl_called_times 0 + +proc get_vl {} { + global hex + global decimal + global gdb_prompt + global gdb_test_name + global get_vl_called_times + + set vl 0x0 + + gdb_test_multiple "info registers \$vl" "$get_vl_called_times call of get_vl()" { + -re "^info registers\[^\r\n\]+\r\n" { + exp_continue + } + + -re "^vl\\s+(${hex})\\s+(${decimal})\r\n" { + set vl $expect_out(2,string) + exp_continue + } + + -re "^$gdb_prompt $" { + pass $gdb_test_name + } + } + + set get_vl_called_times [expr {$get_vl_called_times + 1}] + + return $vl +} + +proc generate_sequence { start step count } { + if {$step == 0 && $count > 8} { + return "$start " + } + + set res "$start" + set count [expr {$count - 1}] + + for {set i 0} {$i < $count} {incr i} { + set start [expr {$start + $step}] + set res "${res}, $start" + } + + return $res +} + +if {![riscv_support_rvv]} { + unsupported "RVV unsupported" + return +} + +if {![riscv_support_rvv_intrinsic]} { + unsupported "RVV intrinsic unsupported" + return +} + +standard_testfile + +set compile_flags {"debug"} +lappend compile_flags "additional_flags=-march=rv64gcv" + +# First, we figure out VLENB value to set correct vector extension to march +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +gdb_breakpoint "$srcfile:[gdb_get_line_number "break 2"]" +gdb_continue_to_breakpoint "preparing stage" +set vlenb [riscvlib_rvv_get_csr vlenb "$testfile"] + +set compile_flags {"debug"} +if {$vlenb >= 16} { + lappend compile_flags "additional_flags=-march=rv64gcv" +} elseif {$vlenb >= 8} { + lappend compile_flags "additional_flags=-march=rv64gc_zve64x" +} else { + unsupported "Unsupported VLENB value: $vlenb" + return +} + +# Here is real test started +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +for {set i 2} {$i <= 13} {incr i} { + gdb_breakpoint "$srcfile:[gdb_get_line_number "break $i"]" +} + +gdb_continue_to_breakpoint "break 2" + +set vl [get_vl] + +gdb_test "print a" "\\{[generate_sequence 42 0 $vl]\\}" +gdb_test "print b" "\\{[generate_sequence 43 0 $vl]\\}" +gdb_test "print c" "\\{[generate_sequence 44 0 $vl]\\}" +gdb_test "print res" "\\{[generate_sequence 129 0 $vl]\\}" +gdb_test "print foo(a, b, c, n)" "\\{[generate_sequence 129 0 $vl]\\}" + +gdb_continue_to_breakpoint "break 3" + +set vl [get_vl] + +gdb_test "print g" "\\{[generate_sequence 48 0 $vl]\\}" +gdb_test "print h" "\\{[generate_sequence 49 0 $vl]\\}" + +gdb_test "print res_1" "\\{[generate_sequence 97 0 $vl]\\}" +gdb_test "print foo1(g, h, n)" "\\{[generate_sequence 97 0 $vl]\\}" + +gdb_test "print res_2" "\\{[generate_sequence 97 0 $vl]\\}" +gdb_test "print foo2(h, g, n)" "\\{[generate_sequence 97 0 $vl]\\}" + +gdb_continue_to_breakpoint "break 4" + +set vl [get_vl] + +gdb_test "print big1" "\\{[generate_sequence 50 0 $vl]\\}" +gdb_test "print big2" "\\{[generate_sequence 51 0 $vl]\\}" +gdb_test "print big3" "\\{[generate_sequence 52 0 $vl]\\}" +gdb_test "print big_res" "\\{[generate_sequence 153 0 $vl]\\}" +gdb_test "print foo3(big1, big2, big3, n)" "\\{[generate_sequence 153 0 $vl]\\}" + +gdb_continue_to_breakpoint "break 5" + +set vl [get_vl] +set repeat_num [expr {$vl / 8 - 1}] + +set pattern_part "101, 51, 101, 51, 51, 101, 51, 101" +set pattern "\\{$pattern_part" +for {set i 0} {$i < $repeat_num} {incr i} { + set pattern "$pattern, $pattern_part" +} +set pattern "$pattern\\}" + +gdb_test "print masked_sum" $pattern +gdb_test "print foo4(big1, big2, mask, mask, n)" $pattern + +gdb_continue_to_breakpoint "break 6" + +set vl [get_vl] + +set pattern "\\{[generate_sequence 0 8 $vl]\\}" + +gdb_test "print rs2" $pattern + +gdb_continue_to_breakpoint "break 7" + +set vl [get_vl] + +set pattern "= \\{\\{[generate_sequence 0 2 $vl].*\\}, \\{[generate_sequence 1 2 $vl].*\\}\\}" + +gdb_test "print a_seg" $pattern + +gdb_continue_to_breakpoint "break 8" + +set vl [get_vl] + +set pattern "= \\{[generate_sequence 0 2 $vl].*\\}" + +gdb_test "print res_a_seg0" $pattern +gdb_test "print foo5_get0(h, a_seg)" $pattern + +gdb_continue_to_breakpoint "break 9" + +set vl [get_vl] + +set pattern "= \\{[generate_sequence 1 2 $vl].*\\}" + +gdb_test "print res_a_seg1" $pattern +gdb_test "print foo5_get1(h, a_seg)" $pattern + +gdb_continue_to_breakpoint "break 10" + +set vl [get_vl] + +set pattern "\\{[generate_sequence 0 8 $vl]\\}" + +gdb_test "print rs2_2" $pattern + +gdb_continue_to_breakpoint "break 11" + +set vl [get_vl] + +set pattern "= \\{\\{[generate_sequence 0 2 $vl].*\\}, \\{[generate_sequence 1 2 $vl].*\\}\\}" + +gdb_test "print b_seg" $pattern + +gdb_continue_to_breakpoint "break 12" + +set vl [get_vl] + +set pattern "= \\{[generate_sequence 0 2 $vl].*\\}" + +gdb_test "print res_b_seg0" $pattern +gdb_test "print foo6_get0(h, b_seg)" $pattern + +gdb_continue_to_breakpoint "break 13" + +set vl [get_vl] + +set pattern "= \\{[generate_sequence 1 2 $vl].*\\}" + +gdb_test "print res_b_seg1" $pattern +gdb_test "print foo6_get1(h, b_seg)" $pattern diff --git a/gdb/testsuite/gdb.arch/riscv-vu-availability.c b/gdb/testsuite/gdb.arch/riscv-vu-availability.c new file mode 100644 index 00000000000..620ecb7142d --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-availability.c @@ -0,0 +1,67 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +asm (".option arch, +v\n"); + +unsigned +do_vlenb_read () +{ + unsigned vlenb; + asm volatile ("csrr %[vlenb], vlenb" : [vlenb] "=r"(vlenb) : :); + return vlenb; +} + +unsigned +do_vsetvli () +{ + unsigned vl; + asm volatile ("vsetvli %[new_vl], x0, e8, m1, ta, ma" + : [new_vl] "=r"(vl) + : + :); + return vl; +} + +#ifdef READ_VLENB_BEFORE_MAIN +unsigned VLENB = do_vlenb_read (); +#endif // READ_VLENB_BEFORE_MAIN + +#ifdef SET_VSETVLI_BEFORE_MAIN +unsigned VL = do_vsetvli (); +#endif // SET_VSETVLI_BEFORE_MAIN + +int STORAGE[64]; + +void +do_vector_stuff () +{ + do_vsetvli (); + asm volatile ("vadd.vi v1, v1, 0x1"); + asm volatile ("vadd.vi v2, v1, 0x2"); + asm volatile ("vs1r.v v1, (%0)" + : + : "r"(STORAGE) + : "memory"); /* pre_vect_mem */ + asm volatile ("vl1re8.v v2, (%0)" : : "r"(STORAGE) : "memory"); +} + +int +main () +{ + do_vector_stuff (); + return 0; /* post_vector_op */ +} diff --git a/gdb/testsuite/gdb.arch/riscv-vu-availability.exp b/gdb/testsuite/gdb.arch/riscv-vu-availability.exp new file mode 100644 index 00000000000..dbbb010f055 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-availability.exp @@ -0,0 +1,72 @@ +# Copyright 2025 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 . + +require {istarget "riscv*-*-*"} + +if {![riscv_support_rvv]} { + unsupported "RVV unsupported" + return +} + +standard_testfile +load_lib riscv64-rvv-lib.exp + +proc initialize_vu_availability_test {extra_args } { + global testfile + global srcfile + + set compile_flags {} + lappend compile_flags debug + lappend compile_flags c++ + lappend compile_flags "additional_flags=-march=rv64gc ${extra_args}" + + if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 + } + + if {![runto_main]} { + return -1 + } +} + +proc test_unavailable_regs { extra_args } { + initialize_vu_availability_test ${extra_args} + gdb_test "print \$vtype" "= " "test vtype unavailable ${extra_args}" + gdb_test "print \$vcsr" "= " "test vcsr unavailable ${extra_args}" + gdb_test "print \$vl" "= " "test vl unavailable ${extra_args}" + gdb_test "print \$vstart" "= " "test vstart unavailable ${extra_args}" + gdb_test "print \$vlenb" "= " "test vlenb unavailable ${extra_args}" + for {set i 0} {$i < 32} {incr i} { + gdb_test "print \$v${i}" "= " "test v${i} unavailable ${extra_args}" + } +} + +proc test_available_regs { extra_args } { + global testfile + initialize_vu_availability_test ${extra_args} + set VLENB [riscvlib_rvv_get_csr vlenb "$testfile"] + gdb_test "print \$vtype" "= 192" "test vtype available ${extra_args}" + gdb_test "print \$vcsr" "= 0" "test vcsr available ${extra_args}" + gdb_test "print \$vl" "= $VLENB" "test vl available ${extra_args}" + gdb_test "print \$vstart" "= 0" "test vstart available ${extra_args}" + gdb_test "print \$vlenb" "= $VLENB" "test vlenb available ${extra_args}" + for {set i 0} {$i < 32} {incr i} { + gdb_test "print \$v${i}" [riscvlib_rvv_vreg_zero_pattern $VLENB] "test v${i} available ${extra_args}" + } +} + +test_unavailable_regs "-DREAD_VLENB_BEFORE_MAIN" +test_unavailable_regs "" +test_available_regs "-DSET_VSETVLI_BEFORE_MAIN" diff --git a/gdb/testsuite/gdb.arch/riscv-vu-consitency-checks.c b/gdb/testsuite/gdb.arch/riscv-vu-consitency-checks.c new file mode 100644 index 00000000000..f392b0a2df3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-consitency-checks.c @@ -0,0 +1,79 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +asm (".option arch, +v\n"); + +#include +#include +#include + +unsigned +do_vlenb_read () +{ + unsigned vlenb; + asm volatile ("csrr %[vlenb], vlenb" : [vlenb] "=r"(vlenb) : :); + return vlenb; +} + +void +reset_vu () +{ + unsigned vl; + asm volatile ("vsetvli %[new_vl], x0, e8, m8, ta, ma" + : [new_vl] "=r"(vl) + : + :); + asm volatile ("vxor.vv v0, v0, v0\n" + "vxor.vv v8, v8, v8\n" + "vxor.vv v16, v16, v16\n" + "vxor.vv v24, v24, v24\n" + "csrrci zero, vxrm, 3\n" + "csrrci zero, vxsat, 1\n"); + asm volatile ("vsetvli %[new_vl], x0, e8, m1, tu, mu" + : [new_vl] "=r"(vl) + : + :); + asm volatile ("nop"); /* vu_reset_end */ +} + +void +do_workload () +{ + unsigned long long app_vtype; + unsigned app_vl; + unsigned app_vlenb; + asm volatile ("csrr %[vtype], vtype\n" : [vtype] "=r"(app_vtype) : :); + asm volatile ("csrr %[vl], vl\n" + : [vl] "=r"(app_vl) /* vect_test_vtype_read */ + : + :); + asm volatile ("csrr %[vlenb], vlenb\n" : [vlenb] "=r"(app_vlenb) : :); + asm volatile ("vxor.vv v24, v16, v8\n" : : :); + asm volatile ("nop"); /* workload_end */ +} + +int +main () +{ + unsigned vlenb_value = do_vlenb_read (); + (void)vlenb_value; + reset_vu (); + /* vect_test_start */ + for (int i = 0; i < 777; ++i) + do_workload (); + return 0; /* vect_test_end */ +} diff --git a/gdb/testsuite/gdb.arch/riscv-vu-consitency-checks.exp b/gdb/testsuite/gdb.arch/riscv-vu-consitency-checks.exp new file mode 100644 index 00000000000..9f52d1dcbd4 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-consitency-checks.exp @@ -0,0 +1,152 @@ +# Copyright 2025 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 . + +require {istarget "riscv*-*-*"} + +if {![riscv_support_rvv]} { + unsupported "RVV unsupported" + return +} + +standard_testfile +load_lib riscv64-rvv-lib.exp + +proc test_vu_consistency_vl_overflow {VLENB} { + set the_proc [lindex [info level 0] 0] + + gdb_continue_to_breakpoint "$the_proc: start" + gdb_test "print app_vtype" "= 0" "$the_proc: app vtype" + gdb_test "print app_vl" "= $VLENB" "$the_proc: app vl" + gdb_test "print app_vlenb" "= $VLENB" "$the_proc: app vlenb" + gdb_test_no_output "set \$vl = 9999" + + gdb_continue_to_breakpoint "$the_proc: vl updated" + gdb_test "print app_vtype" "= 0" "$the_proc: app vtype - after vl update" + gdb_test "print app_vl" "= $VLENB" "$the_proc: app vl - after vl update" + gdb_test "print app_vlenb" "= $VLENB" "$the_proc: app vlenb - after vl update" + gdb_test "print \$vl" "= $VLENB" "$the_proc: ptraced vl - after vl update" +} + +proc test_vu_coherent_vl_lmul_downgrade {VLENB} { + set the_proc [lindex [info level 0] 0] + + gdb_continue_to_breakpoint "$the_proc: start" + gdb_test_no_output "set \$vtype = 3" + + gdb_continue_to_breakpoint "$the_proc: run with updated LMUL 8" + gdb_test_no_output "set \$vl = 9999" "set \$vl = 9999 large value" + + gdb_continue_to_breakpoint "$the_proc: run with updated large vl" + gdb_test "print app_vtype" "= 3" "$the_proc: app vtype - after vtype LMUL 8 update" + gdb_test "print app_vl" "= [expr {$VLENB * 8}]" "$the_proc: app vl - after vl LMUL 8 update" + gdb_test "print app_vlenb" "= $VLENB" "$the_proc: app vlenb - after LMUL 8 update" + gdb_test "print \$vl" "= [expr {$VLENB * 8}]" "$the_proc: ptraced vl - VLENB * 8" + gdb_test "print \$vtype" "= 3" "$the_proc: ptraced vtype - 3" + + gdb_continue_to_breakpoint "$the_proc: going to switch LMUL back to 1" + gdb_test_no_output "set \$vtype = 0" + + gdb_continue_to_breakpoint "$the_proc: LMUL should be 1" + gdb_test "print app_vtype" "= 0" "$the_proc: app vtype - after LMUL 1 update" + gdb_test "print app_vl" "= $VLENB" "$the_proc: app vl - after LMUL 1 update" + gdb_test "print app_vlenb" "= $VLENB" "$the_proc: app vlenb - after LMUL 1 update" + gdb_test "print \$vl" "= $VLENB" "$the_proc: ptraced vl - after LMUL 1 update" + gdb_test "print \$vtype" "= 0" "$the_proc: ptraced vtype - after LMUL 1 update" +} + +proc test_vu_coherent_non_zero_vstart {VLENB} { + set the_proc [lindex [info level 0] 0] + gdb_continue_to_breakpoint "$the_proc: messing up vstart" + gdb_test_no_output "set \$vstart = 8" + + gdb_continue_to_breakpoint "$the_proc: vstart was 8" + gdb_test "print \$vstart" "= 0" "$the_proc: ptraced vstart - after vstart update" +} + +proc test_vu_consistency_incorrect_vtype {VLENB} { + global srcfile + set the_proc [lindex [info level 0] 0] + if {$VLENB >= 64} { + untested "$the_proc: VLENB must be less than 64" + return + } + gdb_continue_to_breakpoint "$the_proc: setting SEW to 64 and LMUL to 1/8" + set incorrect_vtype [expr { 5 | (3 << 3)}] + gdb_test_no_output "set \$vtype = $incorrect_vtype" + gdb_test "stepi" ".*" "$the_proc: stepi after incorrect" + # kernel BUG: this should not match + gdb_test "print/ \$vtype" "= 0x8000000000000000" "$the_proc: ptraced vtype - after setting illegal mode" + + gdb_breakpoint $srcfile:[gdb_get_line_number vect_test_vtype_read] temporary + gdb_continue_to_breakpoint "$the_proc: app vtype read" + gdb_test "print/x app_vtype" "= 0x8000000000000000" "$the_proc: app vtype- after setting illegal mode" + gdb_test "print/ \$vtype" "= 0x8000000000000000" "$the_proc: ptraced vtype - still illegal" + gdb_test_no_output "set \$vtype = 0" "$the_proc: legalizing vtype" + + gdb_continue_to_breakpoint "$the_proc: vtype is legal again" + gdb_test "print app_vl" "= 0" "$the_proc: app vl - after vtype legalized" + gdb_test "print app_vlenb" "= $VLENB" "$the_proc: app vlenb - after vtype legalized" + # kernel BUG: this should match app_vl + gdb_test "print \$vl" "= 0" "$the_proc: ptraced vl - after vtype legalizied" + gdb_test "print \$vtype" "= 0" "$the_proc: ptraced vtype - after vtype legalized" + gdb_test_no_output "set \$vl = $VLENB" "$the_proc: setting vl after vtype legalized" + + gdb_continue_to_breakpoint "$the_proc: everything is legalized" + gdb_test "print app_vl" "= $VLENB" "$the_proc: app vl - really legal app vl" + gdb_test "print app_vlenb" "= $VLENB" "$the_proc: app vlenb - really legal app vtype" + gdb_test "print \$vl" "= $VLENB" "$the_proc: ptraced vl - really legal" + gdb_test "print \$vtype" "= 0" "$the_proc: ptraced vtype - really legal" +} + +proc test_vu_do_consistency_test {VLENB} { + global srcfile + gdb_breakpoint "$srcfile:[gdb_get_line_number workload_end]" + + gdb_continue_to_breakpoint "warm up" + + test_vu_consistency_vl_overflow $VLENB + test_vu_coherent_vl_lmul_downgrade $VLENB + test_vu_coherent_non_zero_vstart $VLENB + test_vu_consistency_incorrect_vtype $VLENB +} + +proc prepare_vu_consistency_test {} { + global testfile + global srcfile + + set compile_flags {} + lappend compile_flags debug + lappend compile_flags "additional_flags=-march=rv64gc" + + if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 + } + + if {![runto_main]} { + return -1 + } + + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_test_start]" + gdb_continue_to_breakpoint "vect_test_start" + + return 0 +} + +if {[prepare_vu_consistency_test]} { + untested "could not initialize" + return -1 +} +set vlenb [riscvlib_rvv_get_csr vlenb "$testfile"] +test_vu_do_consistency_test $vlenb diff --git a/gdb/testsuite/gdb.arch/riscv-vu-ctx-print.c b/gdb/testsuite/gdb.arch/riscv-vu-ctx-print.c new file mode 100644 index 00000000000..b947c7834ea --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-ctx-print.c @@ -0,0 +1,106 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +#include + +asm (".option arch, +v\n"); + +enum VLMUL +{ + LMUL1 = 0, + LMUL2 = 1, + LMUL4 = 2, + LMUL8 = 3, + LMUL_F8 = 5, + LMUL_F4 = 6, + LMUL_F2 = 7 +}; + +enum SEW +{ + SEW8 = 0, + SEW16 = 1, + SEW32 = 2, + SEW64 = 3, +}; + +unsigned +do_vsetvli () +{ + unsigned vl; + asm volatile ("vsetvli %[new_vl], x0, e8, m1, ta, ma" + : [new_vl] "=r"(vl) + : + :); + return vl; +} + +unsigned +do_vsetv (unsigned vl, VLMUL vlmul, SEW vsew, unsigned vta, unsigned vma) +{ + unsigned vtype + = (unsigned)vlmul | ((unsigned)vsew << 3) | (vta << 6) | (vma << 7); + asm volatile ("vsetvl %[new_vl], %[new_vl], %[vtype]" + : [new_vl] "+r"(vl) + : [vtype] "r"(vtype) + :); + return vl; /* vsetvl_done */ +} + +int STORAGE[64]; + +void +do_vector_stuff () +{ + std::vector vlmul = { + VLMUL::LMUL1, VLMUL::LMUL2, VLMUL::LMUL4, VLMUL::LMUL8, + VLMUL::LMUL_F8, VLMUL::LMUL_F4, VLMUL::LMUL_F2, + }; + std::vector vsew = { + SEW::SEW8, + SEW::SEW16, + SEW::SEW32, + SEW::SEW64, + }; + for (auto vlmul : vlmul) + for (auto sew : vsew) + for (int vta = 0; vta < 2; ++vta) + for (int vma = 0; vma < 2; ++vma) + for (int vl = 1; vl < 3; ++vl) + do_vsetv (vl, vlmul, sew, vta, vma); + + asm volatile ("csrw vxrm, %[rnd_m]" : : [rnd_m] "i"(0) :); + asm volatile ("csrw vxrm, %[rnd_m]" : : [rnd_m] "i"(1) :); /* vxrm_0 */ + asm volatile ("csrw vxrm, %[rnd_m]" : : [rnd_m] "i"(2) :); /* vxrm_1 */ + asm volatile ("csrw vxrm, %[rnd_m]" : : [rnd_m] "i"(3) :); /* vxrm_2 */ + asm volatile ("csrw vxsat, %[vxsat]" : : [vxsat] "i"(1) :); /* vxrm_3 */ + asm volatile ("csrw vxrm, %[rnd_m]" : : [rnd_m] "i"(0) :); /* vxrm_0_again */ + unsigned vtype = -1; + unsigned vl = -1; + asm volatile ("vsetvl %[new_vl], %[new_vl], %[vtype]" + : [new_vl] "+r"(vl), [vtype] "=r"(vtype) + : + :); /* vcsr_done */ +} + +int +main () +{ + do_vsetvli (); + do_vector_stuff (); /* rvv_initialized */ + return 0; /* do_vector_stuff_done */ +} diff --git a/gdb/testsuite/gdb.arch/riscv-vu-ctx-print.exp b/gdb/testsuite/gdb.arch/riscv-vu-ctx-print.exp new file mode 100644 index 00000000000..9c4c6079be6 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-ctx-print.exp @@ -0,0 +1,107 @@ +# Copyright 2025 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 . + +require {istarget "riscv*-*-*"} + +if {![riscv_support_rvv]} { + unsupported "RVV unsupported" + return +} + +standard_testfile +load_lib riscv64-rvv-lib.exp + +proc test_vu_ctx_printouts {VLENB} { + global testfile + global srcfile + global hex + + array set vlmul { 0 1 1 2 2 4 3 8 7 1/2 6 1/4 5 1/8 } + array set vsew { 0 e8 1 e16 2 e32 3 e64 } + array set vta { 0 tu 1 ta } + array set vma { 0 mu 1 ma } + gdb_breakpoint "$srcfile:[gdb_get_line_number vsetvl_done]" + + foreach lmul [lsort -integer [array names vlmul]] { + foreach sew [lsort -integer [array names vsew]] { + foreach ta [lsort -integer [array names vta]] { + foreach ma [lsort -integer [array names vma]] { + foreach vl {1 2} { + set slmul $vlmul($lmul) + set ssew $vsew($sew) + set sta $vta($ta) + set sma $vma($ma) + set case_id "vlmul: $lmul, sew: $sew, ta: $ta, ma: $ma, vl: $vl" + gdb_continue_to_breakpoint "vsetvl_done lmul / $case_id" + + if {![riscvlib_is_vlmul_vsew_legal $VLENB $lmul $sew]} { + set vtype_pattern "vill:1" + } else { + set vtype_pattern "$hex\tLMUL:$lmul \\($slmul\\) SEW:$sew \\($ssew\\) vta:$ta \\($sta\\) vma:$ma \\($sma\\) vill:0" + } + gdb_test "info reg vtype" "${vtype_pattern}" "info reg vtype: $case_id" + set fvl [riscvlib_get_allowed_vl $VLENB $lmul $sew $vl] + gdb_test "info reg vl" "^vl\\s+[format 0x%x $fvl]\t$fvl" "info reg vl: $case_id, fvl: $fvl" + } + } + } + } + } + + foreach vxrm {0 1 2 3} { + gdb_breakpoint "$srcfile:[gdb_get_line_number vxrm_$vxrm]" + gdb_continue_to_breakpoint "vxrm_$vxrm" + set vcsr_value_hex [format 0x%x [expr { ($vxrm << 1) }]] + gdb_test "info reg vcsr" "^vcsr\\s+$vcsr_value_hex\tVXSAT:0 VXRM:$vxrm" "info reg vcsr: vxrm_$vxrm" + } + + gdb_breakpoint "$srcfile:[gdb_get_line_number vxrm_0_again]" + gdb_continue_to_breakpoint "vxrm_0_again" + gdb_test "info reg vcsr" "^vcsr\\s+0x7\tVXSAT:1 VXRM:3" "info reg vcsr: vxsat_1" + + gdb_breakpoint "$srcfile:[gdb_get_line_number vcsr_done]" + gdb_continue_to_breakpoint "vcsr_done" + gdb_test "info reg vcsr" "^vcsr\\s+0x1\tVXSAT:1 VXRM:0" "info reg vcsr: vxsat_1_vxrm0" +} + +proc prepare_vu_printout_test {} { + global testfile + global srcfile + + set compile_flags {} + lappend compile_flags debug + lappend compile_flags c++ + lappend compile_flags "additional_flags=-march=rv64gc" + + if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 + } + + if {![runto_main]} { + return -1 + } + + return 0 +} + +if {[prepare_vu_printout_test]} { + untested "could not initialize" + return -1 +} +gdb_breakpoint "$srcfile:[gdb_get_line_number rvv_initialized]" +gdb_continue_to_breakpoint "rvv_initialized" +set vlenb [riscvlib_rvv_get_csr vlenb "$testfile"] + +test_vu_ctx_printouts $vlenb diff --git a/gdb/testsuite/gdb.arch/riscv-vu-printout.c b/gdb/testsuite/gdb.arch/riscv-vu-printout.c new file mode 100644 index 00000000000..c87f71d8ee2 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-printout.c @@ -0,0 +1,69 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +#include +#include + +asm (".option arch, +v\n"); + +unsigned +do_vlenb_read () +{ + unsigned vlenb; + asm volatile ("csrr %[vlenb], vlenb" : [vlenb] "=r"(vlenb) : :); + return vlenb; +} + +unsigned +do_vsetvli () +{ + unsigned vl; + asm volatile ("vsetvli %[new_vl], x0, e8, m8, tu, mu" + : [new_vl] "=r"(vl) + : + :); + return vl; +} + +char *STORAGE; + +void +do_vector_stuff () +{ + unsigned vlenb_value = do_vlenb_read (); + STORAGE = (char *)calloc (1, vlenb_value * CHAR_BIT); + do_vsetvli (); + asm volatile ("vxor.vv v0, v0, v0"); + asm volatile ("vxor.vv v8, v8, v8"); + asm volatile ("vxor.vv v16, v16, v16"); + asm volatile ("vxor.vv v24, v24, v24"); + asm volatile ("vsetvli t0, x0, e8, m1, tu, mu" : : : "t0"); + asm volatile ("vadd.vi v1, v1, 0x1"); + asm volatile ("vadd.vi v2, v1, 0x2"); + asm volatile ("vs1r.v v1, (%0)" + : + : "r"(STORAGE) + : "memory"); /* pre_vect_mem */ + asm volatile ("vl1re8.v v2, (%0)" : : "r"(STORAGE) : "memory"); +} + +int +main () +{ + do_vector_stuff (); + return 0; /* post_vector_op */ +} diff --git a/gdb/testsuite/gdb.arch/riscv-vu-printout.exp b/gdb/testsuite/gdb.arch/riscv-vu-printout.exp new file mode 100644 index 00000000000..e2fd65f4d9d --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-printout.exp @@ -0,0 +1,92 @@ +# Copyright 2025 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 . + +require {istarget "riscv*-*-*"} + +if {![riscv_support_rvv]} { + unsupported "RVV unsupported" + return +} + +standard_testfile +load_lib riscv64-rvv-lib.exp + +proc test_vu_printouts {VLENB} { + global srcfile + + set vtype_pattern "0x0\tLMUL:0 \\(1\\) SEW:0 \\(e8\\) vta:0 \\(tu\\) vma:0 \\(mu\\) vill:0" + gdb_test "info reg vtype" "${vtype_pattern}" "printout info reg vtype" + gdb_test "info reg vcsr" "0x0\tVXSAT:0 VXRM:0" "printout info reg vcsr" + gdb_test "info reg vl" "[format 0x%x $VLENB]\t$VLENB" "printout info reg vl" + gdb_test "info reg vstart" "0x0\t0" "printout info reg vstart" + gdb_test "info reg vlenb" "[format 0x%x $VLENB]\t$VLENB" "printout info reg vlenb" + + set zero_pattern [riscvlib_rvv_vreg_zero_pattern $VLENB] + gdb_test "print \$v0" ${zero_pattern} "printout print v0" + gdb_test "print \$v1" [riscvlib_rvv_vreg_1_pattern $VLENB] "printout print v1" + gdb_test "print \$v2" [riscvlib_rvv_vreg_3_pattern $VLENB] "printout print v2" + for {set i 3} {$i < 32} {incr i} { + gdb_test "print \$v${i}" ${zero_pattern} "printout print v${i}" + } + + set vregs [capture_command_output "info registers vector" ""] + foreach {- regname} [regexp -all -inline -line {^(\w+)\s+} $vregs] { + incr vreg_arr($regname) + } + set expected_list { vtype vcsr vl vstart vlenb } + for {set i 0 } { $i < 32 } { incr i } { + lappend expected_list v$i + } + set s_expc_list [lsort $expected_list] + set s_vreg_list [lsort [array names vreg_arr]] + if {![string equal $s_expc_list $s_vreg_list]} { + fail "info registers vector (contents)" + } + foreach reg $expected_list { + if { $vreg_arr($reg) != 1 } { + fail "info registers vector has duplicated $reg" + } else { + pass "info register vector has $reg" + } + } +} + +proc prepare_vu_printout_test {} { + global testfile + global srcfile + + set compile_flags {} + lappend compile_flags debug + lappend compile_flags "additional_flags=-march=rv64gc" + + if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 + } + + if {![runto_main]} { + return -1 + } + + gdb_breakpoint "$srcfile:[gdb_get_line_number pre_vect_mem]" + gdb_continue_to_breakpoint "pre_vect_mem" + return 0 +} + +if {[prepare_vu_printout_test]} { + untested "could not initialize" + return -1 +} +set vlenb [riscvlib_rvv_get_csr vlenb "$testfile"] +test_vu_printouts $vlenb diff --git a/gdb/testsuite/gdb.arch/riscv-vu-rvv-unsupported.c b/gdb/testsuite/gdb.arch/riscv-vu-rvv-unsupported.c new file mode 100644 index 00000000000..8a9284e5a5f --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-rvv-unsupported.c @@ -0,0 +1,23 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +int +main () +{ + int a = 42; + return 0; /* break 2 */ +} diff --git a/gdb/testsuite/gdb.arch/riscv-vu-rvv-unsupported.exp b/gdb/testsuite/gdb.arch/riscv-vu-rvv-unsupported.exp new file mode 100644 index 00000000000..7205ec8d810 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-rvv-unsupported.exp @@ -0,0 +1,46 @@ +# Copyright 2025 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 . + +require {istarget "riscv*-*-*"} + +if {[riscv_support_rvv]} { + unsupported "need to run on targets without RVV support" + return +} + +standard_testfile + +set compile_flags {"debug"} +lappend compile_flags "additional_flags=-march=rv64gcv" + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +gdb_breakpoint "$srcfile:[gdb_get_line_number "break 2"]" +gdb_continue_to_breakpoint "break 2" + +gdb_test "print a" " = 42" + +set a0_val 42 +set a0_hex_val 0x[format %x $a0_val] +gdb_test_no_output "set \$a0 = $a0_val" +gdb_test "info reg a0" "a0\[ \t\]+$a0_hex_val\[ \t\]+$a0_val" + +gdb_test "info reg v0" "Invalid register `v0'" diff --git a/gdb/testsuite/gdb.arch/riscv-vu-rwr.c b/gdb/testsuite/gdb.arch/riscv-vu-rwr.c new file mode 100644 index 00000000000..05874b1fdb3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-rwr.c @@ -0,0 +1,62 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +asm (".option arch, +v\n"); + +#include +#include + +unsigned +do_vlenb_read () +{ + unsigned vlenb; + asm volatile ("csrr %[vlenb], vlenb" : [vlenb] "=r"(vlenb) : :); + return vlenb; +} + +void +reset_vu () +{ + unsigned vl; + asm volatile ("vsetvli %[new_vl], x0, e8, m8, ta, ma" + : [new_vl] "=r"(vl) + : + :); + asm volatile ("vxor.vv v0, v0, v0\n" + "vxor.vv v8, v8, v8\n" + "vxor.vv v16, v16, v16\n" + "vxor.vv v24, v24, v24\n" + "vadd.vi v0, v0, 15\n" + "vadd.vi v8, v8, 15\n" + "vadd.vi v16, v16, 15\n" + "vadd.vi v24, v24, 15\n" + "csrrsi zero, vxrm, 3\n" + "csrrsi zero, vxsat, 1\n"); + asm volatile ("nop"); /* vu_reset_end */ +} + +int +main () +{ + unsigned vlenb_value = do_vlenb_read (); + (void)vlenb_value; + reset_vu (); + /* vect_test_start */ + for (int i = 0; i < 777; ++i) + reset_vu (); + return 0; /* vect_test_end */ +} diff --git a/gdb/testsuite/gdb.arch/riscv-vu-rwr.exp b/gdb/testsuite/gdb.arch/riscv-vu-rwr.exp new file mode 100644 index 00000000000..ba8269e6b98 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-rwr.exp @@ -0,0 +1,163 @@ +# Copyright 2025 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 . + +require {istarget "riscv*-*-*"} + +if {![riscv_support_rvv]} { + unsupported "RVV unsupported" + return +} + +standard_testfile +load_lib riscv64-rvv-lib.exp + +proc test_vu_rwr_get_default_vtype_pattern {} { + return "0xc3\tLMUL:3 \\(8\\) SEW:0 \\(e8\\) vta:1 \\(ta\\) vma:1 \\(ma\\) vill:0" +} +proc test_vu_rwr_get_zero_vtype_pattern {} { + return "0x0\tLMUL:0 \\(1\\) SEW:0 \\(e8\\) vta:0 \\(tu\\) vma:0 \\(mu\\) vill:0" +} +proc test_vu_rwr_get_default_vl {VLENB} { + return [expr $VLENB * 8] +} + +proc test_vu_rwr_is_reg_excluded {excluded reg} { + return [expr { [lsearch -exact $excluded $reg] != -1 }] +} + +proc test_vu_rwr_csr_scan { VLENB test_info exclude } { + set the_proc [lindex [info level 0] 0] + if {![test_vu_rwr_is_reg_excluded $exclude "vtype"]} { + set vtype_pattern [test_vu_rwr_get_default_vtype_pattern] + gdb_test "info reg vtype" $vtype_pattern "$the_proc: info reg vtype - $test_info" + } + if {![test_vu_rwr_is_reg_excluded $exclude "vcsr"]} { + gdb_test "info reg vcsr" "0x7\tVXSAT:1 VXRM:3" "$the_proc: info reg vcsr - $test_info" + } + if {![test_vu_rwr_is_reg_excluded $exclude "vl"]} { + set vl [test_vu_rwr_get_default_vl $VLENB] + gdb_test "info reg vl" "[format 0x%x $vl]\t$vl" "$the_proc: info reg vl - $test_info" + } + if {![test_vu_rwr_is_reg_excluded $exclude "vstart"]} { + gdb_test "info reg vstart" "0x0\t0" "$the_proc: info reg vstart - $test_info" + } + if {![test_vu_rwr_is_reg_excluded $exclude "vlenb"]} { + gdb_test "info reg vlenb" "[format 0x%x $VLENB]\t$VLENB" "$the_proc: info reg vlenb - $test_info" + } +} + +proc test_vu_rwr_scan_context {VLENB test_info exclude} { + test_vu_rwr_csr_scan $VLENB $test_info $exclude + set 15_pattern [riscvlib_rvv_vreg_15_pattern $VLENB] + set the_proc [lindex [info level 0] 0] + + for {set i 0} {$i < 32} {incr i} { + if { $exclude eq "v$i" } { + continue + } + gdb_test "print \$v$i" ${15_pattern} "$the_proc: print v$i - $test_info" + } +} + +proc test_vu_rwr {VLENB} { + global srcfile + + set the_proc [lindex [info level 0] 0] + set i8_fmt [riscvlib_rvv_vreg_fmt8] + test_vu_rwr_scan_context $VLENB "initial-scan" "" + + gdb_breakpoint "$srcfile:[gdb_get_line_number vu_reset_end]" + gdb_continue_to_breakpoint "vu_reset_end" + + for {set i 0} {$i < 32} {incr i} { + gdb_continue_to_breakpoint "vu_reset_end - v$i" + set vreg_contents {} + for { set j 0} {$j < $VLENB } { incr j } { + gdb_test_no_output "set \$v$i.${i8_fmt}\[$j\] = $j" + lappend vreg_contents $j + } + test_vu_rwr_scan_context $VLENB "v$i update-scan" "v$i" + + set vreg_pattern [join $vreg_contents ", "] + gdb_test "print \$v$i" "\\\{$i8_fmt = \\{$vreg_pattern\\},.+" "print v$i - after modification" + } + + gdb_continue_to_breakpoint "vu_reset_end - vtype" + gdb_test_no_output "set \$vtype = 0" + test_vu_rwr_scan_context $VLENB "vtype update-scan" {vtype vl} + set zero_vtype_pattern [test_vu_rwr_get_zero_vtype_pattern] + set default_vl [test_vu_rwr_get_default_vl $VLENB] + gdb_test "info reg vtype" $zero_vtype_pattern "$the_proc: info reg vtype - csr update" + gdb_test "info reg vl" "[format 0x%x $default_vl]\t$default_vl" "$the_proc: info reg vl - vl after vtype update" + gdb_test "stepi" ".*" "$the_proc: stepi after vtype update" + gdb_test "info reg vtype" $zero_vtype_pattern "$the_proc: info reg vtype - csr update and stepi" + gdb_test "info reg vl" "[format 0x%x $default_vl]\t$default_vl" "$the_proc: info reg vl - vl after vtype update and stepi" + + gdb_continue_to_breakpoint "vu_reset_end - vcsr" + gdb_test_no_output "set \$vcsr = 0" + test_vu_rwr_scan_context $VLENB "vcsr update-scan" "vcsr" + gdb_test "info reg vcsr" "0x0\tVXSAT:0 VXRM:0" "$the_proc: info reg vcsr - csr update" + gdb_test "stepi" ".*" "$the_proc: stepi after vcsr update" + gdb_test "info reg vcsr" "0x0\tVXSAT:0 VXRM:0" "$the_proc: info reg vcsr - after stepi" + + gdb_continue_to_breakpoint "vu_reset_end - vl" + gdb_test_no_output "set \$vl = 2" + test_vu_rwr_scan_context $VLENB "vl update-scan" "vl" + gdb_test "info reg vl" "[format 0x%x 2]\t2" "$the_proc: info reg vl - csr update" + gdb_test "stepi" ".*" "$the_proc: stepi after vl update" + gdb_test "info reg vl" "0x2\t2" "$the_proc: info reg vl - after stepi" + + gdb_continue_to_breakpoint "vu_reset_end - vstart" + gdb_test_no_output "set \$vstart = 2" + test_vu_rwr_scan_context $VLENB "vstart update-scan" "vstart" + gdb_test "info reg vstart" "0x2\t2" "$the_proc: info reg vstart - vsart update" + gdb_test "stepi" ".*" "$the_proc: stepi after vstart update" + gdb_test "info reg vstart" "0x2\t2" "$the_proc: info reg vstart - after stepi" + + gdb_continue_to_breakpoint "vu_reset_end - vlenb" + gdb_test_no_output "set \$vlenb = 0" + test_vu_rwr_scan_context $VLENB "$the_proc: vlenb update-scan" "" + gdb_test "stepi" ".*" "$the_proc: stepi after vlenb update" + test_vu_rwr_scan_context $VLENB "$the_proc: final scan after stepi" "" +} + +proc prepare_vu_rwr_test {} { + global testfile + global srcfile + + set compile_flags {} + lappend compile_flags debug + lappend compile_flags "additional_flags=-march=rv64gc" + + if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 + } + + if {![runto_main]} { + return -1 + } + + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_test_start]" + gdb_continue_to_breakpoint "vect_test_start" + + return 0 +} + +if {[prepare_vu_rwr_test]} { + untested "could not initialize" + return -1 +} +set vlenb [riscvlib_rvv_get_csr vlenb "$testfile"] +test_vu_rwr $vlenb diff --git a/gdb/testsuite/gdb.arch/riscv-vu-side-effects.c b/gdb/testsuite/gdb.arch/riscv-vu-side-effects.c new file mode 100644 index 00000000000..138d2895dad --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-side-effects.c @@ -0,0 +1,86 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2025 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 . */ + +asm (".option arch, +v\n"); + +#include +#include + +unsigned +do_vlenb_read () +{ + unsigned vlenb; + asm volatile ("csrr %[vlenb], vlenb" : [vlenb] "=r"(vlenb) : :); + return vlenb; +} + +char *STORAGE; + +void +zero_out_vu () +{ + unsigned vl; + asm volatile ("vsetvli %[new_vl], x0, e8, m8, tu, mu" + : [new_vl] "=r"(vl) + : + :); + asm volatile ("vxor.vv v0, v0, v0"); + asm volatile ("vxor.vv v8, v8, v8"); + asm volatile ("vxor.vv v16, v16, v16"); + asm volatile ("vxor.vv v24, v24, v24"); +} + +void +do_wide_operations () +{ + unsigned vl; + asm volatile ("vsetvli %[new_vl], x0, e8, m8, tu, mu" + : [new_vl] "=r"(vl) + : + :); + asm volatile ("vadd.vi v0, v0, 0x1"); /* vect_wide_op_start */ + asm volatile ("vadd.vi v24, v0, 0x2"); /* vect_op_v0_add1 */ + asm volatile ("vadd.vi v16, v8, 0x2"); /* vect_op_v24_v0_add2 */ + asm volatile ("vadd.vi v10, v9, 0x3"); /* vect_op_v16_v8_add2 */ + asm volatile ("nop"); /* vect_wide_op_end */ +} + +void +do_controlled_vadd () +{ + unsigned vl; + asm volatile ("vsetvli %[new_vl], x0, e8, m1, tu, mu" + : [new_vl] "=r"(vl) + : + :); + asm volatile ("vadd.vv v2, v1, v0"); /* vect_control_vadd_start */ + asm volatile ("nop"); /* controlled_vadd_done */ +} + +int +main () +{ + unsigned vlenb_value = do_vlenb_read (); + STORAGE = (char *)calloc (1, vlenb_value * CHAR_BIT); + + zero_out_vu (); + /* vect_test_start */ + do_controlled_vadd (); + zero_out_vu (); + do_wide_operations (); + return 0; /* vect_test_end */ +} diff --git a/gdb/testsuite/gdb.arch/riscv-vu-side-effects.exp b/gdb/testsuite/gdb.arch/riscv-vu-side-effects.exp new file mode 100644 index 00000000000..e96dd421db8 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-vu-side-effects.exp @@ -0,0 +1,162 @@ +# Copyright 2025 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 . + +require {istarget "riscv*-*-*"} + +if {![riscv_support_rvv]} { + unsupported "RVV unsupported" + return +} + +standard_testfile +load_lib riscv64-rvv-lib.exp + +proc test_vu_controlled_add {VLENB} { + global srcfile + + set i8_fmt [riscvlib_rvv_vreg_fmt8] + set zero_pattern [riscvlib_rvv_vreg_zero_pattern $VLENB] + + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_control_vadd_start]" + gdb_continue_to_breakpoint "vect_control_vadd_start" + + set the_proc [lindex [info level 0] 0] + + # ensure that state is pristine + for { set vregn 0 } { $vregn < 32 } { incr vregn } { + gdb_test "print \$v${vregn}" ${zero_pattern} "$the_proc: print v${vregn} - pristine" + } + + # update v0 + for {set i 0} {$i < $VLENB} {incr i} { + set val [expr {$i % 256 - 128}] + gdb_test_no_output "set \$v0.${i8_fmt}\[$i\] = $val" + lappend v0_contents $val + } + + # update v1 + for {set i 0} {$i < $VLENB} {incr i} { + set val [expr {($i + 7) % 256 - 128}] + gdb_test_no_output "set \$v1.${i8_fmt}\[$i\] = $val" + lappend v1_contents $val + } + + gdb_breakpoint "$srcfile:[gdb_get_line_number controlled_vadd_done]" + # execute addition operation, v3 register must be updated to summ of v0 and v1 + gdb_continue_to_breakpoint "controlled_vadd_done" + + set v0_pattern [join $v0_contents ", "] + gdb_test "print \$v0" "\\\{$i8_fmt = \\{$v0_pattern\\},.+" "$the_proc: print v0 - after add" + + set v1_pattern [join $v1_contents ", "] + gdb_test "print \$v1" "\\\{$i8_fmt = \\{$v1_pattern\\},.+" "$the_proc: print v1 - after add" + for {set i 0} {$i < $VLENB} {incr i} { + lappend v2_contents [expr {($i + $i + 7 + 128) % 256 - 128}] + } + set v2_pattern [join $v2_contents ", "] + gdb_test "print \$v2" "\\\{$i8_fmt = \\{$v2_pattern\\},.+" "$the_proc: print v2 - add result" + for { set vregn 3 } { $vregn < 32 } { incr vregn } { + gdb_test "print \$v${vregn}" ${zero_pattern} "$the_proc: print v${vregn} - pristine after add" + } +} + +proc test_vu_wide_operations {VLENB} { + global srcfile + + set i8_fmt [riscvlib_rvv_vreg_fmt8] + set the_proc [lindex [info level 0] 0] + + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_wide_op_start]" + gdb_continue_to_breakpoint "vect_wide_op_start" + + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_op_v0_add1]" + gdb_continue_to_breakpoint "vect_op_v0_add1" + + gdb_test_no_output "set \$vl = 2" + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_op_v24_v0_add2]" + gdb_continue_to_breakpoint "vect_op_v24_v0_add2" + + for {set i 0} {$i < $VLENB} {incr i} { + gdb_test_no_output "set \$v8.${i8_fmt}\[$i\] = $i" + lappend v8_contents $i + } + + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_op_v16_v8_add2]" + gdb_continue_to_breakpoint "vect_op_v16_v8_add2" + + gdb_test_no_output "set \$vtype = 0" + + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_wide_op_end]" + gdb_continue_to_breakpoint "vect_wide_op_end" + + set vtype_pattern "0x0\tLMUL:0 \\(1\\) SEW:0 \\(e8\\) vta:0 \\(tu\\) vma:0 \\(mu\\) vill:0" + gdb_test "info reg vtype" "${vtype_pattern}" "$the_proc: info reg vtype - end state" + gdb_test "info reg vcsr" "0x0\tVXSAT:0 VXRM:0" "$the_proc: info reg vcsr - end state" + gdb_test "info reg vl" "[format 0x%x 2]\t2" "$the_proc: info reg vl - end state" + gdb_test "info reg vstart" "0x0\t0" "$the_proc: info reg vstart - end state" + gdb_test "info reg vlenb" "[format 0x%x $VLENB]\t$VLENB" "$the_proc: info reg vlenb - end state" + + set zero_pattern [riscvlib_rvv_vreg_zero_pattern $VLENB] + set ones_pattern [riscvlib_rvv_vreg_1_pattern $VLENB] + foreach vregn { 0 1 2 3 4 5 6 7 } { + gdb_test "print \$v${vregn}" ${ones_pattern} "$the_proc: print v${vregn} - end state" + } + foreach vregn { 9 11 12 13 14 15 17 18 19 20 21 22 23 25 26 27 28 29 30 31} { + gdb_test "print \$v${vregn}" ${zero_pattern} "$the_proc: print v${vregn} - end state" + } + set xn_zeroes_rep [riscvlib_rvv_vreg_component_pattern [expr {$VLENB - 2}] 0] + # for VLENB = 16 we have: + # v10 \{i8 = {3, 3, 0 } ... + # v16 \{i8 = {2, 3, 0 } ... + # v24 \{i8 = {3, 3, 0 } ... + foreach vregn { 10 24 } { + gdb_test "print \$v${vregn}" "\\\{$i8_fmt = \\{3, 3, ${xn_zeroes_rep}\\},.+" "$the_proc: print v${vregn} - end state" + } + gdb_test "print \$v16" "\\\{$i8_fmt = \\{2, 3, ${xn_zeroes_rep}\\},.+" "$the_proc: print v16 - end state" + + # v8 \{i8 = {0, 1, 2, ...} .... + set v8_pattern [join $v8_contents ", "] + gdb_test "print \$v8" "\\\{$i8_fmt = \\{$v8_pattern\\},.+" "$the_proc: print v8 - end state" +} + +proc prepare_vu_rw_test {} { + global testfile + global srcfile + + set compile_flags {} + lappend compile_flags debug + lappend compile_flags "additional_flags=-march=rv64gc" + + if {[prepare_for_testing "failed to prepare" $testfile $srcfile $compile_flags]} { + return -1 + } + + if {![runto_main]} { + return -1 + } + + gdb_breakpoint "$srcfile:[gdb_get_line_number vect_test_start]" + gdb_continue_to_breakpoint "vect_test_start" + + return 0 +} + +if {[prepare_vu_rw_test]} { + untested "could not initialize" + return -1 +} +set vlenb [riscvlib_rvv_get_csr vlenb "$testfile"] +test_vu_controlled_add $vlenb +test_vu_wide_operations $vlenb diff --git a/gdb/testsuite/lib/riscv64-rvv-lib.exp b/gdb/testsuite/lib/riscv64-rvv-lib.exp new file mode 100644 index 00000000000..ada5a9c052d --- /dev/null +++ b/gdb/testsuite/lib/riscv64-rvv-lib.exp @@ -0,0 +1,166 @@ +proc riscvlib_is_vlmul_vsew_legal {VLENB vlmul vsew} { + # vlmul == 5 => 1/8 + # vlmul == 6 => 1/4 + # vlmul == 7 => 1/2 + set sew [expr {1 << ($vsew + 3)}] + if {$vlmul > 4} { + set lmul_modifier [expr {1 << (8 - $vlmul)}] + set required_vlen [expr {$sew * $lmul_modifier}] + set vlen [expr {$VLENB * 8}] + return [expr {$vlen >= $required_vlen}]; + } + if {$vlmul < 4} { + set lmul_modifier [expr {1 << $vlmul}] + set required_vlen $sew + set vlen [expr {$VLENB * 8 * $lmul_modifier}] + return [expr {$vlen >= $required_vlen}] + } + + return 0; +} + +proc riscvlib_get_allowed_vl {VLENB vlmul vsew vl} { + # vlmul == 5 => 1/8 + # vlmul == 6 => 1/4 + # vlmul == 7 => 1/2 + # dummy way to filter-out illegal cases + if {![riscvlib_is_vlmul_vsew_legal $VLENB $vlmul $vsew]} { + return 0 + } + set sew [expr {1 << ($vsew + 3)}] + set vlen [expr {$VLENB * 8}] + set vlmax 0 + + if {$vlmul > 4} { + set lmul_modifier [expr {1 << (8 - $vlmul)}] + set vlmax [expr {$vlen / ($lmul_modifier * $sew)}] + } + + if {$vlmul < 4} { + set lmul_modifier [expr {1 << $vlmul}] + set vlmax [expr {$vlen * $lmul_modifier / $sew}] + } + + if {$vl > $vlmax} { + return $vlmax + } + + return $vl +} + +proc riscvlib_rvv_get_csr {name test_id} { + global hex + global decimal + global gdb_prompt + global gdb_test_name + + gdb_test_multiple "info registers $name" "" { + -re "^info registers\[^\r\n\]+\r\n" { + exp_continue + } + -re "^$name\\s+(${hex})\\s+\[^\n]+\r\n" { + set value [expr {$expect_out(1,string)}] + exp_continue + } + -re "^$gdb_prompt $" { + pass "$gdb_test_name $test_id" + } + } + return $value +} + +proc riscvlib_rvv_vreg_fmt8 {} { + return i8 +} +proc riscvlib_rvv_vreg_fmt16 {} { + return i16 +} +proc riscvlib_rvv_vreg_fmt32 {} { + return i32 +} +proc riscvlib_rvv_vreg_fmt64 {} { + return i64 +} + +proc riscvlib_rvv_vreg_print_pattern { i8 i16 i32 i64 half f32 f64} { + set I8_FMT [riscvlib_rvv_vreg_fmt8] + set I16_FMT [riscvlib_rvv_vreg_fmt16] + set I32_FMT [riscvlib_rvv_vreg_fmt32] + set I64_FMT [riscvlib_rvv_vreg_fmt64] + set HALF_FMT half + set F32_FMT f32 + set F64_FMT f64 + return [join [list \ + "\\\{${I8_FMT} = \\{$i8\\}" \ + "${I16_FMT} = \\{$i16\\}" \ + "${I32_FMT} = \\{$i32\\}" \ + "${I64_FMT} = \\{$i64\\}" \ + "${HALF_FMT} = \\{$half\\}" \ + "${F32_FMT} = \\{$f32\\}" \ + "${F64_FMT} = \\{$f64\\}\\\}" \ + ] ", "] +} + +proc riscvlib_rvv_vreg_component_pattern {repeat_count symbol {collapse_allowed 1}} { + if { $collapse_allowed } { + if { $repeat_count > 8 } { + return "$symbol " + } + } + return [join [lrepeat $repeat_count $symbol] ", "] +} + +proc riscvlib_rvv_vreg_zero_pattern {vlenb} { + set zero_symbol 0 + set pattern [list \ + [riscvlib_rvv_vreg_component_pattern $vlenb $zero_symbol] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 2 }] $zero_symbol] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 4 }] $zero_symbol] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 8 }] $zero_symbol] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 2 }] $zero_symbol] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 4 }] $zero_symbol] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 8 }] $zero_symbol] \ + ] + return [riscvlib_rvv_vreg_print_pattern {*}$pattern] +} + +proc riscvlib_rvv_vreg_1_pattern {vlenb} { + set pattern [list \ + [riscvlib_rvv_vreg_component_pattern $vlenb 1] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 2 }] 257] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 4 }] 16843009] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 8 }] 72340172838076673] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 2 }] 1.5318e-05] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 4 }] 2.36942783e-38] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 8 }] 7.7486041854893479e-304] \ + ] + return [riscvlib_rvv_vreg_print_pattern {*}$pattern] +} + +proc riscvlib_rvv_vreg_3_pattern {vlenb} { + set zero_symbol 0 + set pattern [list \ + [riscvlib_rvv_vreg_component_pattern $vlenb 3] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 2 }] 771] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 4 }] 50529027] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 8 }] 217020518514230019] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 2 }] 4.5955e-05] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 4 }] 3.85008973e-37] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 8 }] 3.7209743448696002e-294] \ + ] + return [riscvlib_rvv_vreg_print_pattern {*}$pattern] +} + +proc riscvlib_rvv_vreg_15_pattern {vlenb} { + set zero_symbol 0 + set pattern [list \ + [riscvlib_rvv_vreg_component_pattern $vlenb 15] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 2 }] 3855] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 4 }] 252645135] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 8 }] 1085102592571150095] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 2 }] 0.00043082] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 4 }] 7.05334452e-30] \ + [riscvlib_rvv_vreg_component_pattern [expr { $vlenb / 8 }] 3.8157368271180168e-236] \ + ] + return [riscvlib_rvv_vreg_print_pattern {*}$pattern] +} -- 2.43.0