Apply inline asm only to vle in indexed load tests When data width is different from index width, lmul is also different. If written in intrinsics, we hit a compiler bug in llvm and gcc that incorrectly combines the vset, causing the vle to see bad lmul. A previous workaround rewrites the tests in inline asm. This new workaround rewrites only the vle part in inline asm, passing the results out as intrinsics-compatible vector data types, allowing the indexed loads to happen in intrinsics. This reduces the number of constraints we need on the asm blocks and reduces the chance of bugs. A bug within indexed load tests' expected output generation is fixed. Change-Id: I7bf1e8a7e9208753e6428a19c178f6f0e40e43e6
diff --git a/tests/cocotb/rvv/load_store/load16_index8.cc b/tests/cocotb/rvv/load_store/load16_index8.cc index b8366a2..2c299ba 100644 --- a/tests/cocotb/rvv/load_store/load16_index8.cc +++ b/tests/cocotb/rvv/load_store/load16_index8.cc
@@ -32,62 +32,122 @@ extern "C" { // Unordered __attribute__((used, retain)) void vluxei8_v_u16mf2() { - auto indices = __riscv_vle8_v_u8mf4(index_buf, vl); + vuint8mf4_t indices; + asm("vsetvli zero, %[vl], e8, mf4, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8mf4(index_buf, vl); auto data = __riscv_vluxei8_v_u16mf2(in_buf, indices, vl); __riscv_vse16_v_u16mf2(out_buf, data, vl); } __attribute__((used, retain)) void vluxei8_v_u16m1() { - auto indices = __riscv_vle8_v_u8mf2(index_buf, vl); + vuint8mf2_t indices; + asm("vsetvli zero, %[vl], e8, mf2, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8mf2(index_buf, vl); auto data = __riscv_vluxei8_v_u16m1(in_buf, indices, vl); __riscv_vse16_v_u16m1(out_buf, data, vl); } __attribute__((used, retain)) void vluxei8_v_u16m2() { - auto indices = __riscv_vle8_v_u8m1(index_buf, vl); + vuint8m1_t indices; + asm("vsetvli zero, %[vl], e8, m1, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m1(index_buf, vl); auto data = __riscv_vluxei8_v_u16m2(in_buf, indices, vl); __riscv_vse16_v_u16m2(out_buf, data, vl); } __attribute__((used, retain)) void vluxei8_v_u16m4() { - auto indices = __riscv_vle8_v_u8m2(index_buf, vl); + vuint8m2_t indices; + asm("vsetvli zero, %[vl], e8, m2, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m2(index_buf, vl); auto data = __riscv_vluxei8_v_u16m4(in_buf, indices, vl); __riscv_vse16_v_u16m4(out_buf, data, vl); } __attribute__((used, retain)) void vluxei8_v_u16m8() { - auto indices = __riscv_vle8_v_u8m4(index_buf, vl); + vuint8m4_t indices; + asm("vsetvli zero, %[vl], e8, m4, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m4(index_buf, vl); auto data = __riscv_vluxei8_v_u16m8(in_buf, indices, vl); __riscv_vse16_v_u16m8(out_buf, data, vl); } // Ordered __attribute__((used, retain)) void vloxei8_v_u16mf2() { - auto indices = __riscv_vle8_v_u8mf4(index_buf, vl); + vuint8mf4_t indices; + asm("vsetvli zero, %[vl], e8, mf4, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8mf4(index_buf, vl); auto data = __riscv_vloxei8_v_u16mf2(in_buf, indices, vl); __riscv_vse16_v_u16mf2(out_buf, data, vl); } __attribute__((used, retain)) void vloxei8_v_u16m1() { - auto indices = __riscv_vle8_v_u8mf2(index_buf, vl); + vuint8mf2_t indices; + asm("vsetvli zero, %[vl], e8, mf2, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8mf2(index_buf, vl); auto data = __riscv_vloxei8_v_u16m1(in_buf, indices, vl); __riscv_vse16_v_u16m1(out_buf, data, vl); } __attribute__((used, retain)) void vloxei8_v_u16m2() { - auto indices = __riscv_vle8_v_u8m1(index_buf, vl); + vuint8m1_t indices; + asm("vsetvli zero, %[vl], e8, m1, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m1(index_buf, vl); auto data = __riscv_vloxei8_v_u16m2(in_buf, indices, vl); __riscv_vse16_v_u16m2(out_buf, data, vl); } __attribute__((used, retain)) void vloxei8_v_u16m4() { - auto indices = __riscv_vle8_v_u8m2(index_buf, vl); + vuint8m2_t indices; + asm("vsetvli zero, %[vl], e8, m2, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m2(index_buf, vl); auto data = __riscv_vloxei8_v_u16m4(in_buf, indices, vl); __riscv_vse16_v_u16m4(out_buf, data, vl); } __attribute__((used, retain)) void vloxei8_v_u16m8() { - auto indices = __riscv_vle8_v_u8m4(index_buf, vl); + vuint8m4_t indices; + asm("vsetvli zero, %[vl], e8, m4, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m4(index_buf, vl); auto data = __riscv_vloxei8_v_u16m8(in_buf, indices, vl); __riscv_vse16_v_u16m8(out_buf, data, vl); }
diff --git a/tests/cocotb/rvv/load_store/load32_index8.cc b/tests/cocotb/rvv/load_store/load32_index8.cc index a3a7a87..069c6d5 100644 --- a/tests/cocotb/rvv/load_store/load32_index8.cc +++ b/tests/cocotb/rvv/load_store/load32_index8.cc
@@ -32,50 +32,98 @@ extern "C" { // Unordered __attribute__((used, retain)) void vluxei8_v_u32m1() { - auto indices = __riscv_vle8_v_u8mf4(index_buf, vl); + vuint8mf4_t indices; + asm("vsetvli zero, %[vl], e8, mf4, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8mf4(index_buf, vl); auto data = __riscv_vluxei8_v_u32m1(in_buf, indices, vl); __riscv_vse32_v_u32m1(out_buf, data, vl); } __attribute__((used, retain)) void vluxei8_v_u32m2() { - auto indices = __riscv_vle8_v_u8mf2(index_buf, vl); + vuint8mf2_t indices; + asm("vsetvli zero, %[vl], e8, mf2, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8mf2(index_buf, vl); auto data = __riscv_vluxei8_v_u32m2(in_buf, indices, vl); __riscv_vse32_v_u32m2(out_buf, data, vl); } __attribute__((used, retain)) void vluxei8_v_u32m4() { - auto indices = __riscv_vle8_v_u8m1(index_buf, vl); + vuint8m1_t indices; + asm("vsetvli zero, %[vl], e8, m1, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m1(index_buf, vl); auto data = __riscv_vluxei8_v_u32m4(in_buf, indices, vl); __riscv_vse32_v_u32m4(out_buf, data, vl); } __attribute__((used, retain)) void vluxei8_v_u32m8() { - auto indices = __riscv_vle8_v_u8m2(index_buf, vl); + vuint8m2_t indices; + asm("vsetvli zero, %[vl], e8, m2, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m2(index_buf, vl); auto data = __riscv_vluxei8_v_u32m8(in_buf, indices, vl); __riscv_vse32_v_u32m8(out_buf, data, vl); } // Ordered __attribute__((used, retain)) void vloxei8_v_u32m1() { - auto indices = __riscv_vle8_v_u8mf4(index_buf, vl); + vuint8mf4_t indices; + asm("vsetvli zero, %[vl], e8, mf4, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8mf4(index_buf, vl); auto data = __riscv_vloxei8_v_u32m1(in_buf, indices, vl); __riscv_vse32_v_u32m1(out_buf, data, vl); } __attribute__((used, retain)) void vloxei8_v_u32m2() { - auto indices = __riscv_vle8_v_u8mf2(index_buf, vl); + vuint8mf2_t indices; + asm("vsetvli zero, %[vl], e8, mf2, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8mf2(index_buf, vl); auto data = __riscv_vloxei8_v_u32m2(in_buf, indices, vl); __riscv_vse32_v_u32m2(out_buf, data, vl); } __attribute__((used, retain)) void vloxei8_v_u32m4() { - auto indices = __riscv_vle8_v_u8m1(index_buf, vl); + vuint8m1_t indices; + asm("vsetvli zero, %[vl], e8, m1, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m1(index_buf, vl); auto data = __riscv_vloxei8_v_u32m4(in_buf, indices, vl); __riscv_vse32_v_u32m4(out_buf, data, vl); } __attribute__((used, retain)) void vloxei8_v_u32m8() { - auto indices = __riscv_vle8_v_u8m2(index_buf, vl); + vuint8m2_t indices; + asm("vsetvli zero, %[vl], e8, m2, ta, ma;" + "vle8.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle8_v_u8m2(index_buf, vl); auto data = __riscv_vloxei8_v_u32m8(in_buf, indices, vl); __riscv_vse32_v_u32m8(out_buf, data, vl); }
diff --git a/tests/cocotb/rvv/load_store/load8_index16.cc b/tests/cocotb/rvv/load_store/load8_index16.cc index 94b0bbe..25b1e2c 100644 --- a/tests/cocotb/rvv/load_store/load8_index16.cc +++ b/tests/cocotb/rvv/load_store/load8_index16.cc
@@ -32,124 +32,124 @@ extern "C" { // Unordered __attribute__((used, retain)) void vluxei16_v_u8mf4() { - auto indices = __riscv_vle16_v_u16mf2(index_buf, vl); + vuint16mf2_t indices; + asm("vsetvli zero, %[vl], e16, mf2, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle16_v_u16mf2(index_buf, vl); auto data = __riscv_vluxei16_v_u8mf4(in_buf, indices, vl); __riscv_vse8_v_u8mf4(out_buf, data, vl); } __attribute__((used, retain)) void vluxei16_v_u8mf2() { - auto indices = __riscv_vle16_v_u16m1(index_buf, vl); + vuint16m1_t indices; + asm("vsetvli zero, %[vl], e16, m1, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle16_v_u16m1(index_buf, vl); auto data = __riscv_vluxei16_v_u8mf2(in_buf, indices, vl); __riscv_vse8_v_u8mf2(out_buf, data, vl); } __attribute__((used, retain)) void vluxei16_v_u8m1() { - asm volatile("vsetvli zero, %0, e16, m2, ta, ma;" - "vle16.v v2, (%1);" - "vsetvli zero, %0, e8, m1, ta, ma;" - "vluxei16.v v2, (%2), v2;" - "vse8.v v2, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v2"); - + vuint16m2_t indices; + asm("vsetvli zero, %[vl], e16, m2, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle16_v_u16m2(index_buf, vl); - // auto data = __riscv_vluxei16_v_u8m1(in_buf, indices, vl); - // __riscv_vse8_v_u8m1(out_buf, data, vl); + auto data = __riscv_vluxei16_v_u8m1(in_buf, indices, vl); + __riscv_vse8_v_u8m1(out_buf, data, vl); } __attribute__((used, retain)) void vluxei16_v_u8m2() { - asm volatile("vsetvli zero, %0, e16, m4, ta, ma;" - "vle16.v v4, (%1);" - "vsetvli zero, %0, e8, m2, ta, ma;" - "vluxei16.v v4, (%2), v4;" - "vse8.v v4, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v4"); - + vuint16m4_t indices; + asm("vsetvli zero, %[vl], e16, m4, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle16_v_u16m4(index_buf, vl); - // auto data = __riscv_vluxei16_v_u8m2(in_buf, indices, vl); - // __riscv_vse8_v_u8m2(out_buf, data, vl); + auto data = __riscv_vluxei16_v_u8m2(in_buf, indices, vl); + __riscv_vse8_v_u8m2(out_buf, data, vl); } __attribute__((used, retain)) void vluxei16_v_u8m4() { - asm volatile("vsetvli zero, %0, e16, m8, ta, ma;" - "vle16.v v8, (%1);" - "vsetvli zero, %0, e8, m4, ta, ma;" - "vluxei16.v v8, (%2), v8;" - "vse8.v v8, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v8"); - + vuint16m8_t indices; + asm("vsetvli zero, %[vl], e16, m8, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle16_v_u16m8(index_buf, vl); - // auto data = __riscv_vluxei16_v_u8m4(in_buf, indices, vl); - // __riscv_vse8_v_u8m4(out_buf, data, vl); + auto data = __riscv_vluxei16_v_u8m4(in_buf, indices, vl); + __riscv_vse8_v_u8m4(out_buf, data, vl); } // Ordered __attribute__((used, retain)) void vloxei16_v_u8mf4() { - auto indices = __riscv_vle16_v_u16mf2(index_buf, vl); + vuint16mf2_t indices; + asm("vsetvli zero, %[vl], e16, mf2, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle16_v_u16mf2(index_buf, vl); auto data = __riscv_vloxei16_v_u8mf4(in_buf, indices, vl); __riscv_vse8_v_u8mf4(out_buf, data, vl); } __attribute__((used, retain)) void vloxei16_v_u8mf2() { - auto indices = __riscv_vle16_v_u16m1(index_buf, vl); + vuint16m1_t indices; + asm("vsetvli zero, %[vl], e16, m1, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle16_v_u16m1(index_buf, vl); auto data = __riscv_vloxei16_v_u8mf2(in_buf, indices, vl); __riscv_vse8_v_u8mf2(out_buf, data, vl); } __attribute__((used, retain)) void vloxei16_v_u8m1() { - asm volatile("vsetvli zero, %0, e16, m2, ta, ma;" - "vle16.v v2, (%1);" - "vsetvli zero, %0, e8, m1, ta, ma;" - "vloxei16.v v2, (%2), v2;" - "vse8.v v2, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v2"); - + vuint16m2_t indices; + asm("vsetvli zero, %[vl], e16, m2, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle16_v_u16m2(index_buf, vl); - // auto data = __riscv_vloxei16_v_u8m1(in_buf, indices, vl); - // __riscv_vse8_v_u8m1(out_buf, data, vl); + auto data = __riscv_vloxei16_v_u8m1(in_buf, indices, vl); + __riscv_vse8_v_u8m1(out_buf, data, vl); } __attribute__((used, retain)) void vloxei16_v_u8m2() { - asm volatile("vsetvli zero, %0, e16, m4, ta, ma;" - "vle16.v v4, (%1);" - "vsetvli zero, %0, e8, m2, ta, ma;" - "vloxei16.v v4, (%2), v4;" - "vse8.v v4, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v4"); - + vuint16m4_t indices; + asm("vsetvli zero, %[vl], e16, m4, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle16_v_u16m4(index_buf, vl); - // auto data = __riscv_vloxei16_v_u8m2(in_buf, indices, vl); - // __riscv_vse8_v_u8m2(out_buf, data, vl); + auto data = __riscv_vloxei16_v_u8m2(in_buf, indices, vl); + __riscv_vse8_v_u8m2(out_buf, data, vl); } __attribute__((used, retain)) void vloxei16_v_u8m4() { - asm volatile("vsetvli zero, %0, e16, m8, ta, ma;" - "vle16.v v8, (%1);" - "vsetvli zero, %0, e8, m4, ta, ma;" - "vloxei16.v v8, (%2), v8;" - "vse8.v v8, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v8"); - + vuint16m8_t indices; + asm("vsetvli zero, %[vl], e16, m8, ta, ma;" + "vle16.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle16_v_u16m8(index_buf, vl); - // auto data = __riscv_vloxei16_v_u8m4(in_buf, indices, vl); - // __riscv_vse8_v_u8m4(out_buf, data, vl); + auto data = __riscv_vloxei16_v_u8m4(in_buf, indices, vl); + __riscv_vse8_v_u8m4(out_buf, data, vl); } }
diff --git a/tests/cocotb/rvv/load_store/load8_index32.cc b/tests/cocotb/rvv/load_store/load8_index32.cc index 071cca0..d28cf38 100644 --- a/tests/cocotb/rvv/load_store/load8_index32.cc +++ b/tests/cocotb/rvv/load_store/load8_index32.cc
@@ -32,112 +32,100 @@ extern "C" { // Unordered __attribute__((used, retain)) void vluxei32_v_u8mf4() { - auto indices = __riscv_vle32_v_u32m1(index_buf, vl); + vuint32m1_t indices; + asm("vsetvli zero, %[vl], e32, m1, ta, ma;" + "vle32.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle32_v_u32m1(index_buf, vl); auto data = __riscv_vluxei32_v_u8mf4(in_buf, indices, vl); __riscv_vse8_v_u8mf4(out_buf, data, vl); } __attribute__((used, retain)) void vluxei32_v_u8mf2() { - asm volatile("vsetvli zero, %0, e32, m2, ta, ma;" - "vle32.v v2, (%1);" - "vsetvli zero, %0, e8, mf2, ta, ma;" - "vluxei32.v v2, (%2), v2;" - "vse8.v v2, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v2"); - + vuint32m2_t indices; + asm("vsetvli zero, %[vl], e32, m2, ta, ma;" + "vle32.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle32_v_u32m2(index_buf, vl); - // auto data = __riscv_vluxei32_v_u8mf2(in_buf, indices, vl); - // __riscv_vse8_v_u8mf2(out_buf, data, vl); + auto data = __riscv_vluxei32_v_u8mf2(in_buf, indices, vl); + __riscv_vse8_v_u8mf2(out_buf, data, vl); } __attribute__((used, retain)) void vluxei32_v_u8m1() { - asm volatile("vsetvli zero, %0, e32, m4, ta, ma;" - "vle32.v v4, (%1);" - "vsetvli zero, %0, e8, m1, ta, ma;" - "vluxei32.v v4, (%2), v4;" - "vse8.v v4, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v4"); - + vuint32m4_t indices; + asm("vsetvli zero, %[vl], e32, m4, ta, ma;" + "vle32.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle32_v_u32m4(index_buf, vl); - // auto data = __riscv_vluxei32_v_u8m1(in_buf, indices, vl); - // __riscv_vse8_v_u8m1(out_buf, data, vl); + auto data = __riscv_vluxei32_v_u8m1(in_buf, indices, vl); + __riscv_vse8_v_u8m1(out_buf, data, vl); } __attribute__((used, retain)) void vluxei32_v_u8m2() { - asm volatile("vsetvli zero, %0, e32, m8, ta, ma;" - "vle32.v v8, (%1);" - "vsetvli zero, %0, e8, m2, ta, ma;" - "vluxei32.v v8, (%2), v8;" - "vse8.v v8, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v8"); - + vuint32m8_t indices; + asm("vsetvli zero, %[vl], e32, m8, ta, ma;" + "vle32.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle32_v_u32m8(index_buf, vl); - // auto data = __riscv_vluxei32_v_u8m2(in_buf, indices, vl); - // __riscv_vse8_v_u8m2(out_buf, data, vl); + auto data = __riscv_vluxei32_v_u8m2(in_buf, indices, vl); + __riscv_vse8_v_u8m2(out_buf, data, vl); } // Ordered __attribute__((used, retain)) void vloxei32_v_u8mf4() { - auto indices = __riscv_vle32_v_u32m1(index_buf, vl); + vuint32m1_t indices; + asm("vsetvli zero, %[vl], e32, m1, ta, ma;" + "vle32.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); + // TODO: Revert once compiler bug is eliminated + // auto indices = __riscv_vle32_v_u32m1(index_buf, vl); auto data = __riscv_vloxei32_v_u8mf4(in_buf, indices, vl); __riscv_vse8_v_u8mf4(out_buf, data, vl); } __attribute__((used, retain)) void vloxei32_v_u8mf2() { - asm volatile("vsetvli zero, %0, e32, m2, ta, ma;" - "vle32.v v2, (%1);" - "vsetvli zero, %0, e8, mf2, ta, ma;" - "vloxei32.v v2, (%2), v2;" - "vse8.v v2, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v2"); - + vuint32m2_t indices; + asm("vsetvli zero, %[vl], e32, m2, ta, ma;" + "vle32.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle32_v_u32m2(index_buf, vl); - // auto data = __riscv_vloxei32_v_u8mf2(in_buf, indices, vl); - // __riscv_vse8_v_u8mf2(out_buf, data, vl); + auto data = __riscv_vloxei32_v_u8mf2(in_buf, indices, vl); + __riscv_vse8_v_u8mf2(out_buf, data, vl); } __attribute__((used, retain)) void vloxei32_v_u8m1() { - asm volatile("vsetvli zero, %0, e32, m4, ta, ma;" - "vle32.v v4, (%1);" - "vsetvli zero, %0, e8, m1, ta, ma;" - "vloxei32.v v4, (%2), v4;" - "vse8.v v4, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v4"); - + vuint32m4_t indices; + asm("vsetvli zero, %[vl], e32, m4, ta, ma;" + "vle32.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle32_v_u32m4(index_buf, vl); - // auto data = __riscv_vloxei32_v_u8m1(in_buf, indices, vl); - // __riscv_vse8_v_u8m1(out_buf, data, vl); + auto data = __riscv_vloxei32_v_u8m1(in_buf, indices, vl); + __riscv_vse8_v_u8m1(out_buf, data, vl); } __attribute__((used, retain)) void vloxei32_v_u8m2() { - asm volatile("vsetvli zero, %0, e32, m8, ta, ma;" - "vle32.v v8, (%1);" - "vsetvli zero, %0, e8, m2, ta, ma;" - "vluxei32.v v8, (%2), v8;" - "vse8.v v8, (%3);" - : - : "r" (vl), "r" (index_buf), "r" (in_buf), "r" (out_buf) - : "v8"); - + vuint32m8_t indices; + asm("vsetvli zero, %[vl], e32, m8, ta, ma;" + "vle32.v %[index], %[index_buf];" + : [index] "=vr"(indices) + : [vl] "r"(vl), [index_buf] "m"(index_buf)); // TODO: Revert once compiler bug is eliminated // auto indices = __riscv_vle32_v_u32m8(index_buf, vl); - // auto data = __riscv_vloxei32_v_u8m2(in_buf, indices, vl); - // __riscv_vse8_v_u8m2(out_buf, data, vl); + auto data = __riscv_vloxei32_v_u8m2(in_buf, indices, vl); + __riscv_vse8_v_u8m2(out_buf, data, vl); } }
diff --git a/tests/cocotb/rvv_load_store_test.py b/tests/cocotb/rvv_load_store_test.py index bc7b0ab..ac9ab84 100644 --- a/tests/cocotb/rvv_load_store_test.py +++ b/tests/cocotb/rvv_load_store_test.py
@@ -147,10 +147,11 @@ indices = rng.integers(0, index_max, out_size, dtype=index_dtype) # Index is in bytes so input needs to be in bytes. input_data = rng.integers(0, 256, in_bytes, dtype=np.uint8) - # Input needs to be reinterpreted. + # Input needs to be reinterpreted. Note indices in use can reach + # beyond index_dtype when dtype is wider than uint8. indices_in_use = np.array([ np.arange(x, x + np.dtype(dtype).itemsize) - for x in indices[:vl].astype(np.uint32)]).astype(index_dtype) + for x in indices[:vl].astype(np.uint32)]) expected_outputs = input_data[indices_in_use].view(dtype)[..., 0] sbz = np.zeros(out_size - vl, dtype=dtype) expected_outputs = np.concat((expected_outputs, sbz)) @@ -621,7 +622,7 @@ return { 'impl': impl, 'vl': vl, - 'in_bytes': 256, + 'in_bytes': 257, # 2 bytes at offset 255 reachable. 'out_size': vl * 2, } @@ -730,7 +731,7 @@ return { 'impl': impl, 'vl': vl, - 'in_bytes': 256, + 'in_bytes': 259, # 4 bytes at offset 255 reachable. 'out_size': vl * 2, }