RISC-V: T-HEAD: Fix wrong instruction encoding for th.vsetvli

Since the particularity of "th.vsetvli" was not taken into account in the
initial support patches for XTheadVector, the program operation failed
due to instruction coding errors. According to T-Head SPEC ([1]), the
"vsetvl" in the XTheadVector extension consists of SEW, LMUL and EDIV,
which is quite different from the "V" extension. Therefore, we cannot
simply reuse the processing of vsetvl in V extension.

We have set up tens of thousands of test cases to ensure that no
further encoding issues are there, and and execute all compiled test
files on real HW and make sure they don't trigger SIGILL.

Ref:
[1] https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf

Co-developed-by: Lifang Xia <lifang_xia@linux.alibaba.com>
Co-developed-by: Christoph Müllner <christoph.muellner@vrull.eu>

gas/ChangeLog:

	* config/tc-riscv.c (validate_riscv_insn): Add handling for
	th.vsetvli.
	(my_getThVsetvliExpression): New function.
	(riscv_ip): Likewise.
	* testsuite/gas/riscv/x-thead-vector.d: Likewise.
	* testsuite/gas/riscv/x-thead-vector.s: Likewise.

include/ChangeLog:

	* opcode/riscv.h (OP_MASK_XTHEADVLMUL): New macro.
	(OP_SH_XTHEADVLMUL): Likewise.
	(OP_MASK_XTHEADVSEW): Likewise.
	(OP_SH_XTHEADVSEW): Likewise.
	(OP_MASK_XTHEADVEDIV): Likewise.
	(OP_SH_XTHEADVEDIV): Likewise.
	(OP_MASK_XTHEADVTYPE_RES): Likewise.
	(OP_SH_XTHEADVTYPE_RES): Likewise.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Likewise.
	* riscv-opc.c: Likewise.
This commit is contained in:
Jin Ma
2024-01-04 10:17:40 +08:00
committed by Nelson Chu
parent 53c4e37bb1
commit 6a95962e25
6 changed files with 128 additions and 2 deletions

View File

@@ -653,6 +653,28 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
bool sign;
switch (*++oparg)
{
case 'V':
++oparg;
if (*oparg != 'c')
goto undefined_modifier;
int imm = (*oparg == 'b') ? EXTRACT_RVV_VB_IMM (l)
: EXTRACT_RVV_VC_IMM (l);
unsigned int imm_vediv = EXTRACT_OPERAND (XTHEADVEDIV, imm);
unsigned int imm_vlmul = EXTRACT_OPERAND (XTHEADVLMUL, imm);
unsigned int imm_vsew = EXTRACT_OPERAND (XTHEADVSEW, imm);
unsigned int imm_vtype_res
= EXTRACT_OPERAND (XTHEADVTYPE_RES, imm);
if (imm_vsew < ARRAY_SIZE (riscv_vsew)
&& imm_vlmul < ARRAY_SIZE (riscv_th_vlen)
&& imm_vediv < ARRAY_SIZE (riscv_th_vediv)
&& ! imm_vtype_res)
print (info->stream, dis_style_text, "%s,%s,%s",
riscv_vsew[imm_vsew], riscv_th_vlen[imm_vlmul],
riscv_th_vediv[imm_vediv]);
else
print (info->stream, dis_style_immediate, "%d", imm);
break;
case 'l': /* Integer immediate, literal. */
oparg++;
while (*oparg && *oparg != ',')