From: Kirill Radkin <kirill.radkin@syntacore.com>
To: <gdb-patches@sourceware.org>
Cc: Kirill Radkin <kirill.radkin@syntacore.com>
Subject: [PATCH 2/2] RISC-V Vector Extension Support Testing
Date: Fri, 7 Nov 2025 19:55:34 +0300 [thread overview]
Message-ID: <20251107165534.1688124-2-kirill.radkin@syntacore.com> (raw)
In-Reply-To: <20251107165534.1688124-1-kirill.radkin@syntacore.com>
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 <riscv_vector.h>
+{% 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} <repeats ${count} times>\\}"
+ }
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+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 <http://www.gnu.org/licenses/>.
+
+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 <http://www.gnu.org/licenses/>. */
+
+#include <riscv_vector.h>
+#include <malloc.h>
+
+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 <http://www.gnu.org/licenses/>.
+
+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 <repeats $count times>"
+ }
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+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 <http://www.gnu.org/licenses/>.
+
+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" "= <unavailable>" "test vtype unavailable ${extra_args}"
+ gdb_test "print \$vcsr" "= <unavailable>" "test vcsr unavailable ${extra_args}"
+ gdb_test "print \$vl" "= <unavailable>" "test vl unavailable ${extra_args}"
+ gdb_test "print \$vstart" "= <unavailable>" "test vstart unavailable ${extra_args}"
+ gdb_test "print \$vlenb" "= <unavailable>" "test vlenb unavailable ${extra_args}"
+ for {set i 0} {$i < 32} {incr i} {
+ gdb_test "print \$v${i}" "= <unavailable>" "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 <http://www.gnu.org/licenses/>. */
+
+asm (".option arch, +v\n");
+
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+
+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 <http://www.gnu.org/licenses/>.
+
+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 <http://www.gnu.org/licenses/>. */
+
+#include <vector>
+
+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 = {
+ VLMUL::LMUL1, VLMUL::LMUL2, VLMUL::LMUL4, VLMUL::LMUL8,
+ VLMUL::LMUL_F8, VLMUL::LMUL_F4, VLMUL::LMUL_F2,
+ };
+ std::vector<SEW> 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 <http://www.gnu.org/licenses/>.
+
+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 <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <limits.h>
+
+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 <http://www.gnu.org/licenses/>.
+
+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 <http://www.gnu.org/licenses/>. */
+
+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 <http://www.gnu.org/licenses/>.
+
+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 <http://www.gnu.org/licenses/>. */
+
+asm (".option arch, +v\n");
+
+#include <stdlib.h>
+#include <limits.h>
+
+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 <http://www.gnu.org/licenses/>.
+
+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 <http://www.gnu.org/licenses/>. */
+
+asm (".option arch, +v\n");
+
+#include <stdlib.h>
+#include <limits.h>
+
+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 <http://www.gnu.org/licenses/>.
+
+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 <repeats 14 times>} ...
+ # v16 \{i8 = {2, 3, 0 <repeats 14 times>} ...
+ # v24 \{i8 = {3, 3, 0 <repeats 14 times>} ...
+ 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 <repeats $repeat_count times>"
+ }
+ }
+ 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
next prev parent reply other threads:[~2025-11-07 16:56 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-07 16:55 [PATCH 1/2] RISC-V Vector Extension Support Kirill Radkin
2025-11-07 16:55 ` Kirill Radkin [this message]
2026-04-13 4:22 [PATCH 2/2] RISC-V Vector Extension Support Testing Jerry Zhang Jian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251107165534.1688124-2-kirill.radkin@syntacore.com \
--to=kirill.radkin@syntacore.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox