summaryrefslogtreecommitdiffstats
path: root/gitlab/issues/target_riscv/host_missing/accel_missing/2422.toml
diff options
context:
space:
mode:
Diffstat (limited to 'gitlab/issues/target_riscv/host_missing/accel_missing/2422.toml')
-rw-r--r--gitlab/issues/target_riscv/host_missing/accel_missing/2422.toml79
1 files changed, 79 insertions, 0 deletions
diff --git a/gitlab/issues/target_riscv/host_missing/accel_missing/2422.toml b/gitlab/issues/target_riscv/host_missing/accel_missing/2422.toml
new file mode 100644
index 00000000..f7f52a2d
--- /dev/null
+++ b/gitlab/issues/target_riscv/host_missing/accel_missing/2422.toml
@@ -0,0 +1,79 @@
+id = 2422
+title = "`vill` not set after reserved `vsetvli` instruction usage"
+state = "opened"
+created_at = "2024-07-03T10:48:26.180Z"
+closed_at = "n/a"
+labels = ["target: riscv"]
+url = "https://gitlab.com/qemu-project/qemu/-/issues/2422"
+host-os = "Ubuntu 24.04"
+host-arch = "x86-64"
+qemu-version = "qemu-riscv64 version 9.0.50 (v9.0.0-1866-gff6d8490e3)"
+guest-os = "n/a"
+guest-arch = "n/a"
+description = """The ["AVL encoding" section of the RISC-V V Spec 1.0](https://github.com/riscv/riscv-isa-manual/blob/main/src/v-st-ext.adoc#avl-encoding) states that a `vsetvli x0,x0,...` that changes VLMAX is reserved and "Implementations may set `vill`" in this case. QEMU does not set `vill` in this case. Doing so would help detect code generation issues and non-portable code.
+
+Here is the quote from the spec:
+
+> When `rs1=x0` and `rd=x0`, the instruction operates as if the current
+> vector length in `vl` is used as the AVL, and the resulting value is
+> written to `vl`, but not to a destination register. This form can
+> only be used when VLMAX and hence `vl` is not actually changed by the
+> new SEW/LMUL ratio. Use of the instruction with a new SEW/LMUL ratio
+> that would result in a change of VLMAX is reserved.
+> Use of the instruction is also reserved if `vill` was 1 beforehand.
+> Implementations may set `vill` in either case.
+
+Note, I have not checked QEMU's behaviour for the other case mentioned in the quote: "Use of the instruction is also reserved if `vill` was 1 beforehand"."""
+reproduce = """1. Create `test.c`
+```C
+#include <assert.h>
+
+/* Position of vill in vtype. */
+
+#define VILL_BIT (__riscv_xlen - 1)
+
+/* Return true if vill is 1. */
+
+int vill_set_p ()
+{
+ __UINT64_TYPE__ vtype;
+ asm volatile ("csrr %0, vtype" : "=r"(vtype));
+
+ return (vtype >> VILL_BIT) & 1;
+}
+
+/* Return true if vill is 0. */
+
+int vill_clear_p ()
+{
+ return !vill_set_p ();
+}
+
+int main ()
+{
+ int vl;
+
+ assert (vill_clear_p ());
+
+ /* Valid: vl = VLMAX. */
+ asm volatile ("vsetvli %0,zero,e64,m8,ta,ma\\n" : "=r"(vl));
+ assert (vill_clear_p ());
+
+ /* Valid: vl and VLMAX not changed. */
+ asm volatile ("vsetvli zero,zero,e64,m8,ta,ma\\n");
+ assert (vill_clear_p ());
+
+ /* Reserved: Reduce VLMAX. */
+ asm volatile ("vsetvli zero,zero,e64,m1,ta,ma\\n");
+ assert (vill_set_p ());
+
+ return 0;
+}
+```
+2. Build `test.c` with `riscv32-unknown-elf-gcc test.c -o test -march=rv64gcv -mabi=lp64d`
+3. Run qemu with `qemu-riscv64 -cpu rv64,v=true test`
+4. The final assertion fails because executing the reserved `vsetvli` did not set `vill`
+```
+assertion "vill_set_p ()" failed: file "test.c", line 40, function: main
+```"""
+additional = "n/a"