This series adds support for the RISC-V Packed SIMD (P) extension for RV32 and RV64.
The P extension defines packed-SIMD fixed-point operations intended for DSP workloads such as multimedia and signal processing. These instructions operate on packed subword elements in general-purpose registers, with register-pair forms for wider operands on RV32. The implementation targets the V0.21 development draft of the RISC-V P extension specification: https://github.com/riscv/riscv-p-spec The local riscv-p-spec reference checkout is at commit: 71b78d2c8d1d41cc01a036d75dc001920b8ac22e P support is enabled with the experimental x-p CPU property. The series includes instruction decoding and translation, helpers, extension-state handling, and the specification-defined control of vxsat. The focus remains functional correctness and instruction coverage; performance optimization is left for future work. This revision adds in-tree TCG tests for RV32 and RV64 and addresses the review feedback on helper reuse, register overlap, shift semantics, and code readability. It also fixes additional issues found while testing, including zero register-pair handling and RV64 SHLR rounding. Thanks to Daniel Henrique Barboza, Nutty Liu, Chao Liu, and Max Chou for their reviews and suggestions. Changes in v3: - Add descriptive commit messages explaining the purpose and behavior of the patches, and document helper macro definitions, including their interfaces and arithmetic semantics. - Add RV32 and RV64 assembly tests under tests/tcg/riscv, with shared test macros and integration into the TCG test Makefiles. Cover arithmetic, shifts, multiplication, narrowing, saturation, register overlap, and zero register-pair operands. The tests are freestanding Linux-user programs and do not require a target libc. Set PSIMD_CC to a P-capable Clang to build them; the assembler options use rv32gp0p21 and rv64gp0p21. Enable previously disabled tests using the P v0.21 mnemonics and update signed saturation immediate operands. - Correct register-controlled packed byte and halfword shifts to use the low five bits of rs2. Share the signed saturating/rounding shift implementation between scalar and packed forms: psshar_hs, psshar_ws, and sshar are all generated by GEN_PSIMD_VAR_SSHAR. Return zero for oversized SSHAR/SHAR right shifts, and widen rounding arithmetic before adding the rounding bit. - Clamp unsigned rounding right shifts to the element width so that the source MSB still participates in rounding for oversized shifts. Apply this to PSSHLR/SSHLR and RV64 SHLR. Use a wider intermediate for SHLR to preserve the carry when rounding UINT64_MAX right by one bit, and add regression tests for these cases. - Fix RV32 register-pair operations when the destination overlaps the scalar source by completing both results before writeback. Treat a zero register-pair selector as {x0, x0}, suppress both destination writes for a zero pair, and preserve vxsat side effects. Use tcg_gen_movi_i64() to initialize a zero source in narrowing translations, with a dedicated regression test. - Avoid undefined behavior in helper arithmetic by using unsigned operations where wraparound is intended and wider intermediates where needed. Handle oversized left shifts explicitly and handle zero shifts in SLX/SRX without shifting by the operand width. - Correct the RV32 REV encoding, reject unavailable translations instead of accepting them without an operation, and fix lane selection in PMQWACC.H and PMQRWACC.H. - Reuse qemu/bitops.h extract64() for lane extraction, correct misleading helper comments, and align macro continuation characters. Testing: The P extension TCG tests were built with LLVM/Clang 24.0.0git (/opt/llvm/bin/clang), llvm-project commit: 96295a1412f9afbee9d4a3c2701e83f5a529a9cc Built qemu-riscv32, qemu-riscv64, qemu-system-riscv32, and qemu-system-riscv64 successfully. Both P extension TCG suites pass with the new regression cases: make -C build/tests/tcg/riscv32-linux-user \ PSIMD_CC=/opt/llvm/bin/clang run-psimd-rv32 make -C build/tests/tcg/riscv64-linux-user \ PSIMD_CC=/opt/llvm/bin/clang run-psimd-rv64 The test targets enable x-p, zmmul, zba, and zbb on the corresponding rv32 or rv64 CPU. The P-aware compiler path is configurable through PSIMD_CC. Changes in v2: - Refactored translation and helper code using macros for common implementation patterns. - Consolidated P extension prerequisite checks in riscv_cpu_validate_p(). - Removed the Zbkb dependency to match the specification. - Added the specification-defined vxsat control mechanism. Previous versions: v2: https://lists.nongnu.org/archive/html/qemu-riscv/2026-07/msg00697.html v1: https://lists.nongnu.org/archive/html/qemu-riscv/2026-04/msg00301.html Feedback on the implementation and tests would be appreciated. Co-authored-by: Yin Zhang <[email protected]> Co-authored-by: Dajun Huang <[email protected]> Co-authored-by: Zhiyuan Yang <[email protected]> Molly Chen (19): target/riscv: Add packed SIMD extension state target/riscv: Add packed SIMD helper framework target/riscv: Add packed SIMD arithmetic instructions target/riscv: Add packed SIMD averaging and rounding instructions target/riscv: Add packed SIMD absolute, difference, compare and mask instructions target/riscv: Add packed SIMD shift instructions target/riscv: Add packed SIMD exchange instructions target/riscv: Add packed SIMD horizontal reduction instructions target/riscv: Add packed SIMD pack, merge and count-leading instructions target/riscv: Add packed SIMD pure multiplication instructions target/riscv: Add packed SIMD multiply-accumulate instructions target/riscv: Add packed SIMD Q-format multiplication instructions target/riscv: Add packed SIMD Q-format MAC instructions target/riscv: Add packed SIMD two-way multiply-add/subtract instructions target/riscv: Add packed SIMD four-way multiply-add instructions target/riscv: Add packed SIMD load-replicate instructions target/riscv: Add packed SIMD RV32 only instructions target/riscv: Remove Zbkb dependency from P extension to align with the spec tests/tcg/riscv: Add tests for the P extension target/riscv/cpu.c | 5 +- target/riscv/cpu.h | 8 + target/riscv/cpu_bits.h | 2 + target/riscv/helper.h | 529 +++ target/riscv/insn32.decode | 830 +++++ target/riscv/machine.c | 19 + target/riscv/tcg/csr.c | 39 +- target/riscv/tcg/insn_trans/trans_rvb.c.inc | 4 +- target/riscv/tcg/insn_trans/trans_rvp.c.inc | 1439 ++++++++ target/riscv/tcg/meson.build | 3 +- target/riscv/tcg/psimd_helper.c | 3536 +++++++++++++++++++ target/riscv/tcg/tcg-cpu.c | 46 + target/riscv/tcg/translate.c | 6 + tests/tcg/riscv/psimd-common.S | 1105 ++++++ tests/tcg/riscv/psimd-rv32.S | 1256 +++++++ tests/tcg/riscv/psimd-rv64.S | 578 +++ tests/tcg/riscv/psimd-test-macros.inc | 952 +++++ tests/tcg/riscv32/Makefile.target | 30 + tests/tcg/riscv64/Makefile.target | 25 + 19 files changed, 10406 insertions(+), 6 deletions(-) create mode 100644 target/riscv/tcg/insn_trans/trans_rvp.c.inc create mode 100644 target/riscv/tcg/psimd_helper.c create mode 100644 tests/tcg/riscv/psimd-common.S create mode 100644 tests/tcg/riscv/psimd-rv32.S create mode 100644 tests/tcg/riscv/psimd-rv64.S create mode 100644 tests/tcg/riscv/psimd-test-macros.inc create mode 100644 tests/tcg/riscv32/Makefile.target base-commit: b23a62773a7856299cbb3782e64968b6a92c792f -- 2.34.1
