diff options
author | Jin Ma <jinma@linux.alibaba.com> | 2024-01-04 10:17:40 +0800 |
---|---|---|
committer | Nelson Chu <nelson@rivosinc.com> | 2024-01-05 09:59:48 +0800 |
commit | 6a95962e258f9ef06050f11c049771a865250c6f (patch) | |
tree | 287f74274d39575ef8311047dbb4df2a8a783f17 /opcodes | |
parent | 53c4e37bb18cb8d13dbe2f595bc2ebb453673771 (diff) |
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.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/riscv-dis.c | 22 | ||||
-rw-r--r-- | opcodes/riscv-opc.c | 14 |
2 files changed, 35 insertions, 1 deletions
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index a511ccb6d07..3019b9a5130 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -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 != ',') diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index af19a4ecd59..fdd05ac75dc 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -110,6 +110,18 @@ const char * const riscv_vma[2] = "mu", "ma" }; +/* XTheadVector, List of vsetvli vlmul constants. */ +const char * const riscv_th_vlen[4] = +{ + "m1", "m2", "m4", "m8" +}; + +/* XTheadVector, List of vsetvli vediv constants. */ +const char * const riscv_th_vediv[4] = +{ + "d1", "d2", "d4", "d8" +}; + /* The FLI.[HSDQ] symbolic constants (NULL for numeric constant). */ const char * const riscv_fli_symval[32] = { @@ -2236,7 +2248,7 @@ const struct riscv_opcode riscv_opcodes[] = /* Vendor-specific (T-Head) XTheadVector instructions. */ {"th.vsetvl", 0, INSN_CLASS_XTHEADVECTOR, "d,s,t", MATCH_VSETVL, MASK_VSETVL, match_opcode, 0}, -{"th.vsetvli", 0, INSN_CLASS_XTHEADVECTOR, "d,s,Vc", MATCH_VSETVLI, MASK_VSETVLI, match_opcode, 0}, +{"th.vsetvli", 0, INSN_CLASS_XTHEADVECTOR, "d,s,XtVc", MATCH_VSETVLI, MASK_VSETVLI, match_opcode, 0}, {"th.vlb.v", 0, INSN_CLASS_XTHEADVECTOR, "Vd,0(s)Vm", MATCH_TH_VLBV, MASK_TH_VLBV, match_opcode, INSN_DREF }, {"th.vlh.v", 0, INSN_CLASS_XTHEADVECTOR, "Vd,0(s)Vm", MATCH_TH_VLHV, MASK_TH_VLHV, match_opcode, INSN_DREF }, {"th.vlw.v", 0, INSN_CLASS_XTHEADVECTOR, "Vd,0(s)Vm", MATCH_TH_VLWV, MASK_TH_VLWV, match_opcode, INSN_DREF }, |