* [PATCH 0/3] RISC-V: Support non-standard encodings (on widening FP ops) @ 2022-11-28 6:39 Tsukasa OI 2022-11-28 6:39 ` [PATCH 1/3] RISC-V: Allocate "various" operand type Tsukasa OI ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: Tsukasa OI @ 2022-11-28 6:39 UTC (permalink / raw) To: Tsukasa OI, Nelson Chu, Kito Cheng, Palmer Dabbelt; +Cc: binutils Hello, Some of the floating point instructions does not depend on the rounding mode despite the existence of rm (rounding mode) field. Such examples are widening conversion instructions. Quoting "11.2 Floating-Point Control and Status Register" from the RISC-V ISA Manual (version 20191213): > Some instructions, including widening conversions, have the rm field but > are nevertheless unaffected by the rounding mode; software should set > their rm field to RNE (000). The latest draft of the ISA Manual is clarified further: Quoting "13.2 Floating-Point Control and Status Register" from the RISC-V ISA Manual (version draft-20221119-5234c63): > Some instructions, including widening conversions, have the rm field but > are nevertheless mathematically unaffected by the rounding mode; software > should set their rm field to RNE (000) but implementations must treat the > rm field as usual (in particular, with regard to decoding legal vs. > reserved encodings). For instance, to encode a FCVT.D.S instruction, we should set its rm field to RNE (0b000). However, FCVT.D.S instruction with non-RNE rm field is still a valid instruction (despite that GAS does not allow specifying any rounding modes on FCVT.D.S) and must handle as a valid instruction when disassembled unless an invalid rounding mode is specified. However, current GNU Binutils only supports disassembling widening conversion instructions with rm field of RNE (0b000) except FCVT.Q.L and FCVT.Q.LU instructions (two instructions supported specifying rounding modes for historical reasons). This patchset (in specific, PATCH 3/3) enables special handling of such instructions by adding two new operand types: 1. "WfM": optional rounding mode where specifying rounding mode is not supported in the past. 2. "Wfm": optional rounding mode where specifying rounding mode is supported in the past (used in FCVT.Q.L and FCVT.Q.LU). I designed this patchset to be configurable (allow implementing S Pawan Kumar's proposal if needed) but the behavior in this patchset is as follows: Disassembler: Optional (non-RNE [!= 0b000]) rounding mode is printed only if: (a) "no-aliases" disassembler option is specified, or (b) the rounding mode is invalid (0b101 / 0b110). I think removing condition (a) might be an option. Because, despite that we can now see the actual rounding mode with condition (a), it's not valid as an assembler mnemonic. Condition (b) is an intentional choice to detect invalid encodings. Still, it could be removed, too (I don't recommend though). Assembler: Specifying optional rounding mode is prohibited (except FCVT.Q.L and FCVT.Q.LU) or accepted with a warning (FCVT.Q.L and FCVT.Q.LU). c.f. S Pawan Kumar's proposal: <https://github.com/riscv-collab/riscv-gnu-toolchain/issues/1089> # Before this patchset: objdump -d (with my comment) 8000002c: 42058553 fcvt.d.s fa0,fa1 80000030: 42059553 .4byte 0x42059553 # Valid (but not recommended) encoding of FCVT.D.S 80000034: 4205a553 .4byte 0x4205a553 # Valid (but not recommended) encoding of FCVT.D.S 80000038: 4205b553 .4byte 0x4205b553 # Valid (but not recommended) encoding of FCVT.D.S 8000003c: 4205c553 .4byte 0x4205c553 # Valid (but not recommended) encoding of FCVT.D.S 80000040: 4205f553 .4byte 0x4205f553 # Valid (but not recommended) encoding of FCVT.D.S 80000044: 4205d553 .4byte 0x4205d553 # Invalid FCVT.D.S (reserved rounding mode 0b101) 80000048: 4205e553 .4byte 0x4205e553 # Invalid FCVT.D.S (reserved rounding mode 0b110) # After this patchset: objdump -d 8000002c: 42058553 fcvt.d.s fa0,fa1 80000030: 42059553 fcvt.d.s fa0,fa1 80000034: 4205a553 fcvt.d.s fa0,fa1 80000038: 4205b553 fcvt.d.s fa0,fa1 8000003c: 4205c553 fcvt.d.s fa0,fa1 80000040: 4205f553 fcvt.d.s fa0,fa1 80000044: 4205d553 fcvt.d.s fa0,fa1,unknown 80000048: 4205e553 fcvt.d.s fa0,fa1,unknown # After this patchset: objdump -M no-aliases -d 8000002c: 42058553 fcvt.d.s fa0,fa1 80000030: 42059553 fcvt.d.s fa0,fa1,rtz 80000034: 4205a553 fcvt.d.s fa0,fa1,rdn 80000038: 4205b553 fcvt.d.s fa0,fa1,rup 8000003c: 4205c553 fcvt.d.s fa0,fa1,rmm 80000040: 4205f553 fcvt.d.s fa0,fa1,dyn 80000044: 4205d553 fcvt.d.s fa0,fa1,unknown 80000048: 4205e553 fcvt.d.s fa0,fa1,unknown Due to my development process, it now depends on the commit ("RISC-V: Allocate "various" operand type": PATCH 1/3) which adds "Wif" operand type (not just "WfM" and "Wfm" which is added by PATCH 3/3). PATCH 1/3 is the same patch as this: <https://sourceware.org/pipermail/binutils/2022-October/123884.html> If requested, I can remove the dependency to PATCH 1/3 (in that case my local development branches will be a bit complex but nothing else happens). Thanks, Tsukasa Tsukasa OI (3): RISC-V: Allocate "various" operand type RISC-V: Reorganize invalid rounding mode test RISC-V: Rounding mode on widening instructions gas/config/tc-riscv.c | 107 +++++++++++++++--- gas/testsuite/gas/riscv/rouding-fail.d | 3 - gas/testsuite/gas/riscv/rouding-fail.l | 3 - gas/testsuite/gas/riscv/rouding-fail.s | 3 - .../gas/riscv/rounding-dis-widening-noalias.d | 13 +++ .../gas/riscv/rounding-dis-widening.d | 13 +++ .../gas/riscv/rounding-dis-widening.s | 8 ++ gas/testsuite/gas/riscv/rounding-fail.d | 3 + gas/testsuite/gas/riscv/rounding-fail.l | 16 +++ gas/testsuite/gas/riscv/rounding-fail.s | 22 ++++ .../gas/riscv/rounding-fcvt.q.l-noalias.d | 15 +++ gas/testsuite/gas/riscv/rounding-fcvt.q.l.d | 15 +++ gas/testsuite/gas/riscv/rounding-fcvt.q.l.l | 3 + gas/testsuite/gas/riscv/rounding-fcvt.q.l.s | 5 + opcodes/riscv-dis.c | 48 +++++++- opcodes/riscv-opc.c | 32 +++--- 16 files changed, 261 insertions(+), 48 deletions(-) delete mode 100644 gas/testsuite/gas/riscv/rouding-fail.d delete mode 100644 gas/testsuite/gas/riscv/rouding-fail.l delete mode 100644 gas/testsuite/gas/riscv/rouding-fail.s create mode 100644 gas/testsuite/gas/riscv/rounding-dis-widening-noalias.d create mode 100644 gas/testsuite/gas/riscv/rounding-dis-widening.d create mode 100644 gas/testsuite/gas/riscv/rounding-dis-widening.s create mode 100644 gas/testsuite/gas/riscv/rounding-fail.d create mode 100644 gas/testsuite/gas/riscv/rounding-fail.l create mode 100644 gas/testsuite/gas/riscv/rounding-fail.s create mode 100644 gas/testsuite/gas/riscv/rounding-fcvt.q.l-noalias.d create mode 100644 gas/testsuite/gas/riscv/rounding-fcvt.q.l.d create mode 100644 gas/testsuite/gas/riscv/rounding-fcvt.q.l.l create mode 100644 gas/testsuite/gas/riscv/rounding-fcvt.q.l.s base-commit: c341f4676af4f9922ca61e1b093d103ed808ae6e -- 2.38.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] RISC-V: Allocate "various" operand type 2022-11-28 6:39 [PATCH 0/3] RISC-V: Support non-standard encodings (on widening FP ops) Tsukasa OI @ 2022-11-28 6:39 ` Tsukasa OI 2022-11-29 2:42 ` Nelson Chu 2022-11-28 6:39 ` [PATCH 2/3] RISC-V: Reorganize invalid rounding mode test Tsukasa OI 2022-11-28 6:39 ` [PATCH 3/3] RISC-V: Rounding mode on widening instructions Tsukasa OI 2 siblings, 1 reply; 6+ messages in thread From: Tsukasa OI @ 2022-11-28 6:39 UTC (permalink / raw) To: Tsukasa OI, Nelson Chu, Kito Cheng, Palmer Dabbelt; +Cc: binutils From: Tsukasa OI <research_trasio@irq.a4lg.com> This commit intends to move operands that require very special handling or operand types that are so minor (e.g. only useful on a few instructions) under "W". I also intend this "W" to be "temporary" operand storage until we can find good two character (or less) operand type. In this commit, prefetch offset operand "f" for 'Zicbop' extension is moved to "Wif" because of its special handling (and allocating single character "f" for this operand type seemed too much). Current expected allocation guideline is as follows: 1. 'W' 2. The most closely related single-letter extension in lowercase (strongly recommended but not mandatory) 3. Identify operand type The author currently plans to allocate following three-character operand types (for operands including instructions from unratified extensions). 1. "Wif" ('Zicbop': fetch offset) 2. "Wfv" (unratified 'Zfa': value operand from FLI.[HSDQ] instructions) 3. "Wfm" / "WfM" 'Zfh', 'F', 'D', 'Q': rounding modes "m" with special handling solely for widening conversion instructions. gas/ChangeLog: * config/tc-riscv.c (validate_riscv_insn, riscv_ip): Move from "f" to "Wif". opcodes/ChangeLog: * riscv-dis.c (print_insn_args): Move from "f" to "Wif". * riscv-opc.c (riscv_opcodes): Reflect new operand type. --- gas/config/tc-riscv.c | 64 +++++++++++++++++++++++++++++++------------ opcodes/riscv-dis.c | 26 ++++++++++++++---- opcodes/riscv-opc.c | 6 ++-- 3 files changed, 71 insertions(+), 25 deletions(-) diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 0682eb355241..bb0e18ac8d52 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1359,7 +1359,6 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break; case 'a': used_bits |= ENCODE_JTYPE_IMM (-1U); break; case 'p': used_bits |= ENCODE_BTYPE_IMM (-1U); break; - case 'f': /* Fall through. */ case 'q': used_bits |= ENCODE_STYPE_IMM (-1U); break; case 'u': used_bits |= ENCODE_UTYPE_IMM (-1U); break; case 'z': break; /* Zero immediate. */ @@ -1386,6 +1385,21 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) goto unknown_validate_operand; } break; + case 'W': /* Various operands. */ + switch (*++oparg) + { + case 'i': + switch (*++oparg) + { + case 'f': used_bits |= ENCODE_STYPE_IMM (-1U); break; + default: + goto unknown_validate_operand; + } + break; + default: + goto unknown_validate_operand; + } + break; case 'X': /* Integer immediate. */ { size_t n; @@ -3401,22 +3415,37 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, imm_expr->X_op = O_absent; continue; - case 'f': /* Prefetch offset, pseudo S-type but lower 5-bits zero. */ - if (riscv_handle_implicit_zero_offset (imm_expr, asarg)) - continue; - my_getExpression (imm_expr, asarg); - check_absolute_expr (ip, imm_expr, false); - if (((unsigned) (imm_expr->X_add_number) & 0x1fU) - || imm_expr->X_add_number >= (signed) RISCV_IMM_REACH / 2 - || imm_expr->X_add_number < -(signed) RISCV_IMM_REACH / 2) - as_bad (_("improper prefetch offset (%ld)"), - (long) imm_expr->X_add_number); - ip->insn_opcode |= - ENCODE_STYPE_IMM ((unsigned) (imm_expr->X_add_number) & - ~ 0x1fU); - imm_expr->X_op = O_absent; - asarg = expr_end; - continue; + case 'W': /* Various operands. */ + switch (*++oparg) + { + case 'i': + switch (*++oparg) + { + case 'f': + /* Prefetch offset for 'Zicbop' extension. + pseudo S-type but lower 5-bits zero. */ + if (riscv_handle_implicit_zero_offset (imm_expr, asarg)) + continue; + my_getExpression (imm_expr, asarg); + check_absolute_expr (ip, imm_expr, false); + if (((unsigned) (imm_expr->X_add_number) & 0x1fU) + || imm_expr->X_add_number >= RISCV_IMM_REACH / 2 + || imm_expr->X_add_number < -RISCV_IMM_REACH / 2) + as_bad (_ ("improper prefetch offset (%ld)"), + (long) imm_expr->X_add_number); + ip->insn_opcode |= ENCODE_STYPE_IMM ( + (unsigned) (imm_expr->X_add_number) & ~0x1fU); + imm_expr->X_op = O_absent; + asarg = expr_end; + continue; + default: + goto unknown_riscv_ip_operand; + } + break; + default: + goto unknown_riscv_ip_operand; + } + break; case 'X': /* Integer immediate. */ { @@ -3469,6 +3498,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, } } break; + default: unknown_riscv_ip_operand: as_fatal (_("internal: unknown argument type `%s'"), diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 0e1f3b4610aa..1e6716e8e58c 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -473,11 +473,6 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info (int)EXTRACT_STYPE_IMM (l)); break; - case 'f': - print (info->stream, dis_style_address_offset, "%d", - (int)EXTRACT_STYPE_IMM (l)); - break; - case 'a': info->target = EXTRACT_JTYPE_IMM (l) + pc; (*info->print_address_func) (info->target, info); @@ -582,6 +577,27 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info print (info->stream, dis_style_immediate, "%d", rs1); break; + case 'W': /* Various operands. */ + { + switch (*++oparg) + { + case 'i': + switch (*++oparg) + { + case 'f': + print (info->stream, dis_style_address_offset, "%d", + (int) EXTRACT_STYPE_IMM (l)); + break; + default: + goto undefined_modifier; + } + break; + default: + goto undefined_modifier; + } + } + break; + case 'X': /* Integer immediate. */ { size_t n; diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 0e691544f9bc..653eb60f2a58 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -313,9 +313,9 @@ const struct riscv_opcode riscv_opcodes[] = /* name, xlen, isa, operands, match, mask, match_func, pinfo. */ /* Standard hints. */ -{"prefetch.i", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 }, -{"prefetch.r", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 }, -{"prefetch.w", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 }, +{"prefetch.i", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 }, +{"prefetch.r", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 }, +{"prefetch.w", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 }, {"pause", 0, INSN_CLASS_ZIHINTPAUSE, "", MATCH_PAUSE, MASK_PAUSE, match_opcode, 0 }, /* Basic RVI instructions and aliases. */ -- 2.38.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] RISC-V: Allocate "various" operand type 2022-11-28 6:39 ` [PATCH 1/3] RISC-V: Allocate "various" operand type Tsukasa OI @ 2022-11-29 2:42 ` Nelson Chu 2022-11-29 3:19 ` Tsukasa OI 0 siblings, 1 reply; 6+ messages in thread From: Nelson Chu @ 2022-11-29 2:42 UTC (permalink / raw) To: Tsukasa OI; +Cc: Kito Cheng, Palmer Dabbelt, binutils On Mon, Nov 28, 2022 at 2:39 PM Tsukasa OI <research_trasio@irq.a4lg.com> wrote: > > From: Tsukasa OI <research_trasio@irq.a4lg.com> > > This commit intends to move operands that require very special handling or > operand types that are so minor (e.g. only useful on a few instructions) > under "W". I also intend this "W" to be "temporary" operand storage until > we can find good two character (or less) operand type. > > In this commit, prefetch offset operand "f" for 'Zicbop' extension is moved > to "Wif" because of its special handling (and allocating single character > "f" for this operand type seemed too much). > > Current expected allocation guideline is as follows: > > 1. 'W' > 2. The most closely related single-letter extension in lowercase > (strongly recommended but not mandatory) > 3. Identify operand type > > The author currently plans to allocate following three-character operand > types (for operands including instructions from unratified extensions). > > 1. "Wif" ('Zicbop': fetch offset) Maybe just "if" without the W? W seems redundant. If the offset is immediate then using "i + <xxx>" seems more clear to understand. > 2. "Wfv" (unratified 'Zfa': value operand from FLI.[HSDQ] instructions) We probably also need to modify other old operand names to comply with the new naming rules. But for now the current operand names seem enough, maybe we can find better naming rules in the future, it's not urgent. > 3. "Wfm" / "WfM" > 'Zfh', 'F', 'D', 'Q': rounding modes "m" with special handling > solely for widening conversion instructions. I still think these similar checks, including the rounding mode checks, should be checked in different match_opcode functions, that should be enough. There is no way to make assembly wrong until you are using the .insn directives, and we don't need to check if the operands are valid or not for them, since .insn is used to allow users to write an unsupported instruction. Please don't continue trying to add various operand names to support these, it is really hard to maintain. I should have already said that, so this is the last time I mention it. Nelson > gas/ChangeLog: > > * config/tc-riscv.c (validate_riscv_insn, riscv_ip): Move from > "f" to "Wif". > > opcodes/ChangeLog: > > * riscv-dis.c (print_insn_args): Move from "f" to "Wif". > * riscv-opc.c (riscv_opcodes): Reflect new operand type. > --- > gas/config/tc-riscv.c | 64 +++++++++++++++++++++++++++++++------------ > opcodes/riscv-dis.c | 26 ++++++++++++++---- > opcodes/riscv-opc.c | 6 ++-- > 3 files changed, 71 insertions(+), 25 deletions(-) > > diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c > index 0682eb355241..bb0e18ac8d52 100644 > --- a/gas/config/tc-riscv.c > +++ b/gas/config/tc-riscv.c > @@ -1359,7 +1359,6 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) > case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break; > case 'a': used_bits |= ENCODE_JTYPE_IMM (-1U); break; > case 'p': used_bits |= ENCODE_BTYPE_IMM (-1U); break; > - case 'f': /* Fall through. */ > case 'q': used_bits |= ENCODE_STYPE_IMM (-1U); break; > case 'u': used_bits |= ENCODE_UTYPE_IMM (-1U); break; > case 'z': break; /* Zero immediate. */ > @@ -1386,6 +1385,21 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) > goto unknown_validate_operand; > } > break; > + case 'W': /* Various operands. */ > + switch (*++oparg) > + { > + case 'i': > + switch (*++oparg) > + { > + case 'f': used_bits |= ENCODE_STYPE_IMM (-1U); break; > + default: > + goto unknown_validate_operand; > + } > + break; > + default: > + goto unknown_validate_operand; > + } > + break; > case 'X': /* Integer immediate. */ > { > size_t n; > @@ -3401,22 +3415,37 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, > imm_expr->X_op = O_absent; > continue; > > - case 'f': /* Prefetch offset, pseudo S-type but lower 5-bits zero. */ > - if (riscv_handle_implicit_zero_offset (imm_expr, asarg)) > - continue; > - my_getExpression (imm_expr, asarg); > - check_absolute_expr (ip, imm_expr, false); > - if (((unsigned) (imm_expr->X_add_number) & 0x1fU) > - || imm_expr->X_add_number >= (signed) RISCV_IMM_REACH / 2 > - || imm_expr->X_add_number < -(signed) RISCV_IMM_REACH / 2) > - as_bad (_("improper prefetch offset (%ld)"), > - (long) imm_expr->X_add_number); > - ip->insn_opcode |= > - ENCODE_STYPE_IMM ((unsigned) (imm_expr->X_add_number) & > - ~ 0x1fU); > - imm_expr->X_op = O_absent; > - asarg = expr_end; > - continue; > + case 'W': /* Various operands. */ > + switch (*++oparg) > + { > + case 'i': > + switch (*++oparg) > + { > + case 'f': > + /* Prefetch offset for 'Zicbop' extension. > + pseudo S-type but lower 5-bits zero. */ > + if (riscv_handle_implicit_zero_offset (imm_expr, asarg)) > + continue; > + my_getExpression (imm_expr, asarg); > + check_absolute_expr (ip, imm_expr, false); > + if (((unsigned) (imm_expr->X_add_number) & 0x1fU) > + || imm_expr->X_add_number >= RISCV_IMM_REACH / 2 > + || imm_expr->X_add_number < -RISCV_IMM_REACH / 2) > + as_bad (_ ("improper prefetch offset (%ld)"), > + (long) imm_expr->X_add_number); > + ip->insn_opcode |= ENCODE_STYPE_IMM ( > + (unsigned) (imm_expr->X_add_number) & ~0x1fU); > + imm_expr->X_op = O_absent; > + asarg = expr_end; > + continue; > + default: > + goto unknown_riscv_ip_operand; > + } > + break; > + default: > + goto unknown_riscv_ip_operand; > + } > + break; > > case 'X': /* Integer immediate. */ > { > @@ -3469,6 +3498,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, > } > } > break; > + > default: > unknown_riscv_ip_operand: > as_fatal (_("internal: unknown argument type `%s'"), > diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c > index 0e1f3b4610aa..1e6716e8e58c 100644 > --- a/opcodes/riscv-dis.c > +++ b/opcodes/riscv-dis.c > @@ -473,11 +473,6 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info > (int)EXTRACT_STYPE_IMM (l)); > break; > > - case 'f': > - print (info->stream, dis_style_address_offset, "%d", > - (int)EXTRACT_STYPE_IMM (l)); > - break; > - > case 'a': > info->target = EXTRACT_JTYPE_IMM (l) + pc; > (*info->print_address_func) (info->target, info); > @@ -582,6 +577,27 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info > print (info->stream, dis_style_immediate, "%d", rs1); > break; > > + case 'W': /* Various operands. */ > + { > + switch (*++oparg) > + { > + case 'i': > + switch (*++oparg) > + { > + case 'f': > + print (info->stream, dis_style_address_offset, "%d", > + (int) EXTRACT_STYPE_IMM (l)); > + break; > + default: > + goto undefined_modifier; > + } > + break; > + default: > + goto undefined_modifier; > + } > + } > + break; > + > case 'X': /* Integer immediate. */ > { > size_t n; > diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c > index 0e691544f9bc..653eb60f2a58 100644 > --- a/opcodes/riscv-opc.c > +++ b/opcodes/riscv-opc.c > @@ -313,9 +313,9 @@ const struct riscv_opcode riscv_opcodes[] = > /* name, xlen, isa, operands, match, mask, match_func, pinfo. */ > > /* Standard hints. */ > -{"prefetch.i", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 }, > -{"prefetch.r", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 }, > -{"prefetch.w", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 }, > +{"prefetch.i", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 }, > +{"prefetch.r", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 }, > +{"prefetch.w", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 }, > {"pause", 0, INSN_CLASS_ZIHINTPAUSE, "", MATCH_PAUSE, MASK_PAUSE, match_opcode, 0 }, > > /* Basic RVI instructions and aliases. */ > -- > 2.38.1 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] RISC-V: Allocate "various" operand type 2022-11-29 2:42 ` Nelson Chu @ 2022-11-29 3:19 ` Tsukasa OI 0 siblings, 0 replies; 6+ messages in thread From: Tsukasa OI @ 2022-11-29 3:19 UTC (permalink / raw) To: Nelson Chu; +Cc: binutils Nelson, Before the real reply... - The reply is going to be pretty long. - I'm not going to reply to you today to stop myself from griping (not to be led by my frustrations) Meanwhile, reviewing <https://sourceware.org/pipermail/binutils/2022-November/124693.html> (at least, PATCH 1-7/11 should be easy to review and partial approval of PATCH 1-7/11 is okay to me) would be nice. Sincerely, Tsukasa On 2022/11/29 11:42, Nelson Chu wrote: > On Mon, Nov 28, 2022 at 2:39 PM Tsukasa OI <research_trasio@irq.a4lg.com> wrote: >> >> From: Tsukasa OI <research_trasio@irq.a4lg.com> >> >> This commit intends to move operands that require very special handling or >> operand types that are so minor (e.g. only useful on a few instructions) >> under "W". I also intend this "W" to be "temporary" operand storage until >> we can find good two character (or less) operand type. >> >> In this commit, prefetch offset operand "f" for 'Zicbop' extension is moved >> to "Wif" because of its special handling (and allocating single character >> "f" for this operand type seemed too much). >> >> Current expected allocation guideline is as follows: >> >> 1. 'W' >> 2. The most closely related single-letter extension in lowercase >> (strongly recommended but not mandatory) >> 3. Identify operand type >> >> The author currently plans to allocate following three-character operand >> types (for operands including instructions from unratified extensions). >> >> 1. "Wif" ('Zicbop': fetch offset) > > Maybe just "if" without the W? W seems redundant. If the offset is > immediate then using "i + <xxx>" seems more clear to understand. > >> 2. "Wfv" (unratified 'Zfa': value operand from FLI.[HSDQ] instructions) > > We probably also need to modify other old operand names to comply with > the new naming rules. But for now the current operand names seem > enough, maybe we can find better naming rules in the future, it's not > urgent. > >> 3. "Wfm" / "WfM" >> 'Zfh', 'F', 'D', 'Q': rounding modes "m" with special handling >> solely for widening conversion instructions. > > I still think these similar checks, including the rounding mode > checks, should be checked in different match_opcode functions, that > should be enough. There is no way to make assembly wrong until you > are using the .insn directives, and we don't need to check if the > operands are valid or not for them, since .insn is used to allow users > to write an unsupported instruction. Please don't continue trying to > add various operand names to support these, it is really hard to > maintain. I should have already said that, so this is the last time I > mention it. > > Nelson > >> gas/ChangeLog: >> >> * config/tc-riscv.c (validate_riscv_insn, riscv_ip): Move from >> "f" to "Wif". >> >> opcodes/ChangeLog: >> >> * riscv-dis.c (print_insn_args): Move from "f" to "Wif". >> * riscv-opc.c (riscv_opcodes): Reflect new operand type. >> --- >> gas/config/tc-riscv.c | 64 +++++++++++++++++++++++++++++++------------ >> opcodes/riscv-dis.c | 26 ++++++++++++++---- >> opcodes/riscv-opc.c | 6 ++-- >> 3 files changed, 71 insertions(+), 25 deletions(-) >> >> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c >> index 0682eb355241..bb0e18ac8d52 100644 >> --- a/gas/config/tc-riscv.c >> +++ b/gas/config/tc-riscv.c >> @@ -1359,7 +1359,6 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) >> case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break; >> case 'a': used_bits |= ENCODE_JTYPE_IMM (-1U); break; >> case 'p': used_bits |= ENCODE_BTYPE_IMM (-1U); break; >> - case 'f': /* Fall through. */ >> case 'q': used_bits |= ENCODE_STYPE_IMM (-1U); break; >> case 'u': used_bits |= ENCODE_UTYPE_IMM (-1U); break; >> case 'z': break; /* Zero immediate. */ >> @@ -1386,6 +1385,21 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) >> goto unknown_validate_operand; >> } >> break; >> + case 'W': /* Various operands. */ >> + switch (*++oparg) >> + { >> + case 'i': >> + switch (*++oparg) >> + { >> + case 'f': used_bits |= ENCODE_STYPE_IMM (-1U); break; >> + default: >> + goto unknown_validate_operand; >> + } >> + break; >> + default: >> + goto unknown_validate_operand; >> + } >> + break; >> case 'X': /* Integer immediate. */ >> { >> size_t n; >> @@ -3401,22 +3415,37 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, >> imm_expr->X_op = O_absent; >> continue; >> >> - case 'f': /* Prefetch offset, pseudo S-type but lower 5-bits zero. */ >> - if (riscv_handle_implicit_zero_offset (imm_expr, asarg)) >> - continue; >> - my_getExpression (imm_expr, asarg); >> - check_absolute_expr (ip, imm_expr, false); >> - if (((unsigned) (imm_expr->X_add_number) & 0x1fU) >> - || imm_expr->X_add_number >= (signed) RISCV_IMM_REACH / 2 >> - || imm_expr->X_add_number < -(signed) RISCV_IMM_REACH / 2) >> - as_bad (_("improper prefetch offset (%ld)"), >> - (long) imm_expr->X_add_number); >> - ip->insn_opcode |= >> - ENCODE_STYPE_IMM ((unsigned) (imm_expr->X_add_number) & >> - ~ 0x1fU); >> - imm_expr->X_op = O_absent; >> - asarg = expr_end; >> - continue; >> + case 'W': /* Various operands. */ >> + switch (*++oparg) >> + { >> + case 'i': >> + switch (*++oparg) >> + { >> + case 'f': >> + /* Prefetch offset for 'Zicbop' extension. >> + pseudo S-type but lower 5-bits zero. */ >> + if (riscv_handle_implicit_zero_offset (imm_expr, asarg)) >> + continue; >> + my_getExpression (imm_expr, asarg); >> + check_absolute_expr (ip, imm_expr, false); >> + if (((unsigned) (imm_expr->X_add_number) & 0x1fU) >> + || imm_expr->X_add_number >= RISCV_IMM_REACH / 2 >> + || imm_expr->X_add_number < -RISCV_IMM_REACH / 2) >> + as_bad (_ ("improper prefetch offset (%ld)"), >> + (long) imm_expr->X_add_number); >> + ip->insn_opcode |= ENCODE_STYPE_IMM ( >> + (unsigned) (imm_expr->X_add_number) & ~0x1fU); >> + imm_expr->X_op = O_absent; >> + asarg = expr_end; >> + continue; >> + default: >> + goto unknown_riscv_ip_operand; >> + } >> + break; >> + default: >> + goto unknown_riscv_ip_operand; >> + } >> + break; >> >> case 'X': /* Integer immediate. */ >> { >> @@ -3469,6 +3498,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, >> } >> } >> break; >> + >> default: >> unknown_riscv_ip_operand: >> as_fatal (_("internal: unknown argument type `%s'"), >> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c >> index 0e1f3b4610aa..1e6716e8e58c 100644 >> --- a/opcodes/riscv-dis.c >> +++ b/opcodes/riscv-dis.c >> @@ -473,11 +473,6 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info >> (int)EXTRACT_STYPE_IMM (l)); >> break; >> >> - case 'f': >> - print (info->stream, dis_style_address_offset, "%d", >> - (int)EXTRACT_STYPE_IMM (l)); >> - break; >> - >> case 'a': >> info->target = EXTRACT_JTYPE_IMM (l) + pc; >> (*info->print_address_func) (info->target, info); >> @@ -582,6 +577,27 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info >> print (info->stream, dis_style_immediate, "%d", rs1); >> break; >> >> + case 'W': /* Various operands. */ >> + { >> + switch (*++oparg) >> + { >> + case 'i': >> + switch (*++oparg) >> + { >> + case 'f': >> + print (info->stream, dis_style_address_offset, "%d", >> + (int) EXTRACT_STYPE_IMM (l)); >> + break; >> + default: >> + goto undefined_modifier; >> + } >> + break; >> + default: >> + goto undefined_modifier; >> + } >> + } >> + break; >> + >> case 'X': /* Integer immediate. */ >> { >> size_t n; >> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c >> index 0e691544f9bc..653eb60f2a58 100644 >> --- a/opcodes/riscv-opc.c >> +++ b/opcodes/riscv-opc.c >> @@ -313,9 +313,9 @@ const struct riscv_opcode riscv_opcodes[] = >> /* name, xlen, isa, operands, match, mask, match_func, pinfo. */ >> >> /* Standard hints. */ >> -{"prefetch.i", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 }, >> -{"prefetch.r", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 }, >> -{"prefetch.w", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 }, >> +{"prefetch.i", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 }, >> +{"prefetch.r", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 }, >> +{"prefetch.w", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 }, >> {"pause", 0, INSN_CLASS_ZIHINTPAUSE, "", MATCH_PAUSE, MASK_PAUSE, match_opcode, 0 }, >> >> /* Basic RVI instructions and aliases. */ >> -- >> 2.38.1 >> > ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/3] RISC-V: Reorganize invalid rounding mode test 2022-11-28 6:39 [PATCH 0/3] RISC-V: Support non-standard encodings (on widening FP ops) Tsukasa OI 2022-11-28 6:39 ` [PATCH 1/3] RISC-V: Allocate "various" operand type Tsukasa OI @ 2022-11-28 6:39 ` Tsukasa OI 2022-11-28 6:39 ` [PATCH 3/3] RISC-V: Rounding mode on widening instructions Tsukasa OI 2 siblings, 0 replies; 6+ messages in thread From: Tsukasa OI @ 2022-11-28 6:39 UTC (permalink / raw) To: Tsukasa OI, Nelson Chu, Kito Cheng, Palmer Dabbelt; +Cc: binutils From: Tsukasa OI <research_trasio@irq.a4lg.com> This commit reorganizes and adds testcases to invalid rounding mode operand test. It also fixes a typo in the filename. gas/ChangeLog: * testsuite/gas/riscv/rounding-fail.d: Rename from rouding-fail. Add some testcases. * testsuite/gas/riscv/rounding-fail.s: Likewise. * testsuite/gas/riscv/rounding-fail.l: Likewise. --- gas/testsuite/gas/riscv/rouding-fail.d | 3 --- gas/testsuite/gas/riscv/rouding-fail.s | 3 --- gas/testsuite/gas/riscv/rounding-fail.d | 3 +++ gas/testsuite/gas/riscv/{rouding-fail.l => rounding-fail.l} | 2 ++ gas/testsuite/gas/riscv/rounding-fail.s | 6 ++++++ 5 files changed, 11 insertions(+), 6 deletions(-) delete mode 100644 gas/testsuite/gas/riscv/rouding-fail.d delete mode 100644 gas/testsuite/gas/riscv/rouding-fail.s create mode 100644 gas/testsuite/gas/riscv/rounding-fail.d rename gas/testsuite/gas/riscv/{rouding-fail.l => rounding-fail.l} (52%) create mode 100644 gas/testsuite/gas/riscv/rounding-fail.s diff --git a/gas/testsuite/gas/riscv/rouding-fail.d b/gas/testsuite/gas/riscv/rouding-fail.d deleted file mode 100644 index 9827b11446db..000000000000 --- a/gas/testsuite/gas/riscv/rouding-fail.d +++ /dev/null @@ -1,3 +0,0 @@ -#as: -march=rv32ifd -#source: rouding-fail.s -#error_output: rouding-fail.l diff --git a/gas/testsuite/gas/riscv/rouding-fail.s b/gas/testsuite/gas/riscv/rouding-fail.s deleted file mode 100644 index d18f53efb503..000000000000 --- a/gas/testsuite/gas/riscv/rouding-fail.s +++ /dev/null @@ -1,3 +0,0 @@ -target: - fadd.s fa1,fa1,fa1, - fadd.d fa1,fa1,fa1, diff --git a/gas/testsuite/gas/riscv/rounding-fail.d b/gas/testsuite/gas/riscv/rounding-fail.d new file mode 100644 index 000000000000..0d0a55818caf --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-fail.d @@ -0,0 +1,3 @@ +#as: -march=rv32ifd +#source: rounding-fail.s +#error_output: rounding-fail.l diff --git a/gas/testsuite/gas/riscv/rouding-fail.l b/gas/testsuite/gas/riscv/rounding-fail.l similarity index 52% rename from gas/testsuite/gas/riscv/rouding-fail.l rename to gas/testsuite/gas/riscv/rounding-fail.l index ea46e7c2d5aa..00d4d8e40fa6 100644 --- a/gas/testsuite/gas/riscv/rouding-fail.l +++ b/gas/testsuite/gas/riscv/rounding-fail.l @@ -1,3 +1,5 @@ .*: Assembler messages: .*: Error: illegal operands `fadd.s fa1,fa1,fa1,' .*: Error: illegal operands `fadd.d fa1,fa1,fa1,' +.*: Error: illegal operands `fadd.s fa1,fa1,fa1,unknown' +.*: Error: illegal operands `fadd.d fa1,fa1,fa1,unknown' diff --git a/gas/testsuite/gas/riscv/rounding-fail.s b/gas/testsuite/gas/riscv/rounding-fail.s new file mode 100644 index 000000000000..6e05cbd410c9 --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-fail.s @@ -0,0 +1,6 @@ +target: + # Invalid rounding modes + fadd.s fa1,fa1,fa1, + fadd.d fa1,fa1,fa1, + fadd.s fa1,fa1,fa1,unknown + fadd.d fa1,fa1,fa1,unknown -- 2.38.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] RISC-V: Rounding mode on widening instructions 2022-11-28 6:39 [PATCH 0/3] RISC-V: Support non-standard encodings (on widening FP ops) Tsukasa OI 2022-11-28 6:39 ` [PATCH 1/3] RISC-V: Allocate "various" operand type Tsukasa OI 2022-11-28 6:39 ` [PATCH 2/3] RISC-V: Reorganize invalid rounding mode test Tsukasa OI @ 2022-11-28 6:39 ` Tsukasa OI 2 siblings, 0 replies; 6+ messages in thread From: Tsukasa OI @ 2022-11-28 6:39 UTC (permalink / raw) To: Tsukasa OI, Nelson Chu, Kito Cheng, Palmer Dabbelt Cc: binutils, S Pawan Kumar From: Tsukasa OI <research_trasio@irq.a4lg.com> This commit adds support for rounding modes on widening instructions to the assembler/disassembler. On the disassembler, non-default rounding mode is displayed when "no-aliases" option is given or the rounding mode itself is invalid. On the assembler, specifying such rounding modes is prohibited unless we have supported in the past. gas/ChangeLog: * config/tc-riscv.c (validate_riscv_insn): Add rounding mode support to widening instructions. (riscv_ip): Likewise. * testsuite/gas/riscv/rounding-dis-widening.d: New disasm test. * testsuite/gas/riscv/rounding-dis-widening.s: Likewise. * testsuite/gas/riscv/rounding-dis-widening-noalias.d: Likewise. * testsuite/gas/riscv/rounding-fail.d: Add testcases for widening instructions. * testsuite/gas/riscv/rounding-fail.l: Likewise. * testsuite/gas/riscv/rounding-fail.s: Likewise. * testsuite/gas/riscv/rounding-fcvt.q.l.d: New test. * testsuite/gas/riscv/rounding-fcvt.q.l.l: Likewise. * testsuite/gas/riscv/rounding-fcvt.q.l.s: Likewise. * testsuite/gas/riscv/rounding-fcvt.q.l-noalias.d: Likewise. opcodes/ChangeLog: * riscv-dis.c (print_insn_args): Add rounding mode support to widening instructions. * riscv-opc.c (riscv_opcodes): Use new operand types. Idea-by: Tsukasa OI <research_trasio@irq.a4lg.com> Idea-by: S Pawan Kumar <pawan.kumar@incoresemi.com> --- gas/config/tc-riscv.c | 43 +++++++++++++++++++ .../gas/riscv/rounding-dis-widening-noalias.d | 13 ++++++ .../gas/riscv/rounding-dis-widening.d | 13 ++++++ .../gas/riscv/rounding-dis-widening.s | 8 ++++ gas/testsuite/gas/riscv/rounding-fail.d | 2 +- gas/testsuite/gas/riscv/rounding-fail.l | 11 +++++ gas/testsuite/gas/riscv/rounding-fail.s | 16 +++++++ .../gas/riscv/rounding-fcvt.q.l-noalias.d | 15 +++++++ gas/testsuite/gas/riscv/rounding-fcvt.q.l.d | 15 +++++++ gas/testsuite/gas/riscv/rounding-fcvt.q.l.l | 3 ++ gas/testsuite/gas/riscv/rounding-fcvt.q.l.s | 5 +++ opcodes/riscv-dis.c | 22 ++++++++++ opcodes/riscv-opc.c | 26 ++++++----- 13 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 gas/testsuite/gas/riscv/rounding-dis-widening-noalias.d create mode 100644 gas/testsuite/gas/riscv/rounding-dis-widening.d create mode 100644 gas/testsuite/gas/riscv/rounding-dis-widening.s create mode 100644 gas/testsuite/gas/riscv/rounding-fcvt.q.l-noalias.d create mode 100644 gas/testsuite/gas/riscv/rounding-fcvt.q.l.d create mode 100644 gas/testsuite/gas/riscv/rounding-fcvt.q.l.l create mode 100644 gas/testsuite/gas/riscv/rounding-fcvt.q.l.s diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index bb0e18ac8d52..f0f531039415 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1396,6 +1396,15 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) goto unknown_validate_operand; } break; + case 'f': + switch (*++oparg) + { + case 'M': /* Fall through. */ + case 'm': USE_BITS (OP_MASK_RM, OP_SH_RM); break; + default: + goto unknown_validate_operand; + } + break; default: goto unknown_validate_operand; } @@ -3442,6 +3451,40 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, goto unknown_riscv_ip_operand; } break; + case 'f': + switch (*++oparg) + { + case 'M': + case 'm': + /* Optional rounding mode (widening conversion) + 'M': operand either disallowed or not recommended + (considered to be non-useful to normal software). + 'm': operand allowed for compatibility reasons + (display a warning instead). */ + if (*asarg == '\0') + { + INSERT_OPERAND (RM, *ip, 0); + continue; + } + else if (*asarg == ',' && asarg++ + && arg_lookup (&asarg, riscv_rm, + ARRAY_SIZE (riscv_rm), ®no)) + { + INSERT_OPERAND (RM, *ip, regno); + if (*oparg == 'M') + as_bad (_ ("rounding mode cannot be specified " + "on widening conversion")); + else + as_warn ( + _ ("specifying a rounding mode is strongly " + "discourged on widening conversion")); + continue; + } + break; + default: + goto unknown_riscv_ip_operand; + } + break; default: goto unknown_riscv_ip_operand; } diff --git a/gas/testsuite/gas/riscv/rounding-dis-widening-noalias.d b/gas/testsuite/gas/riscv/rounding-dis-widening-noalias.d new file mode 100644 index 000000000000..3330b1db83db --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-dis-widening-noalias.d @@ -0,0 +1,13 @@ +#as: -march=rv32ifd +#source: rounding-dis-widening.s +#objdump: -d -M no-aliases + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <target>: +[ ]+[0-9a-f]+:[ ]+420100d3[ ]+fcvt\.d\.s[ ]+ft1,ft2 +[ ]+[0-9a-f]+:[ ]+420100d3[ ]+fcvt\.d\.s[ ]+ft1,ft2 +[ ]+[0-9a-f]+:[ ]+420170d3[ ]+fcvt\.d\.s[ ]+ft1,ft2,dyn diff --git a/gas/testsuite/gas/riscv/rounding-dis-widening.d b/gas/testsuite/gas/riscv/rounding-dis-widening.d new file mode 100644 index 000000000000..8fb31ab39efa --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-dis-widening.d @@ -0,0 +1,13 @@ +#as: -march=rv32ifd +#source: rounding-dis-widening.s +#objdump: -d + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <target>: +[ ]+[0-9a-f]+:[ ]+420100d3[ ]+fcvt\.d\.s[ ]+ft1,ft2 +[ ]+[0-9a-f]+:[ ]+420100d3[ ]+fcvt\.d\.s[ ]+ft1,ft2 +[ ]+[0-9a-f]+:[ ]+420170d3[ ]+fcvt\.d\.s[ ]+ft1,ft2 diff --git a/gas/testsuite/gas/riscv/rounding-dis-widening.s b/gas/testsuite/gas/riscv/rounding-dis-widening.s new file mode 100644 index 000000000000..17443b0a0343 --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-dis-widening.s @@ -0,0 +1,8 @@ +target: + fcvt.d.s ft1, ft2 + # Standard encoding: + # - 2nd operand is the rounding mode (RNE [0b000] is preferred). + # - 6th operand (additional function) is zero for FCVT.D.S. + .insn r OP_FP, 0x0, 0x21, ft1, ft2, f0 + # Non-standard encoding + .insn r OP_FP, 0x7, 0x21, ft1, ft2, f0 diff --git a/gas/testsuite/gas/riscv/rounding-fail.d b/gas/testsuite/gas/riscv/rounding-fail.d index 0d0a55818caf..7857ab75145c 100644 --- a/gas/testsuite/gas/riscv/rounding-fail.d +++ b/gas/testsuite/gas/riscv/rounding-fail.d @@ -1,3 +1,3 @@ -#as: -march=rv32ifd +#as: -march=rv32ifdq_zfh #source: rounding-fail.s #error_output: rounding-fail.l diff --git a/gas/testsuite/gas/riscv/rounding-fail.l b/gas/testsuite/gas/riscv/rounding-fail.l index 00d4d8e40fa6..69d359a0eba4 100644 --- a/gas/testsuite/gas/riscv/rounding-fail.l +++ b/gas/testsuite/gas/riscv/rounding-fail.l @@ -3,3 +3,14 @@ .*: Error: illegal operands `fadd.d fa1,fa1,fa1,' .*: Error: illegal operands `fadd.s fa1,fa1,fa1,unknown' .*: Error: illegal operands `fadd.d fa1,fa1,fa1,unknown' +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: rounding mode cannot be specified on widening conversion +.*: Error: illegal operands `fcvt\.q\.wu ft1,t0,unknown' diff --git a/gas/testsuite/gas/riscv/rounding-fail.s b/gas/testsuite/gas/riscv/rounding-fail.s index 6e05cbd410c9..75f9fe1965d1 100644 --- a/gas/testsuite/gas/riscv/rounding-fail.s +++ b/gas/testsuite/gas/riscv/rounding-fail.s @@ -4,3 +4,19 @@ target: fadd.d fa1,fa1,fa1, fadd.s fa1,fa1,fa1,unknown fadd.d fa1,fa1,fa1,unknown + + # Rounding mode cannot be specified on widening conversion + # unless we have supported in the past. + fcvt.s.h ft1,ft2,dyn + fcvt.d.h ft1,ft2,dyn + fcvt.q.h ft1,ft2,dyn + fcvt.d.s ft1,ft2,dyn + fcvt.q.s ft1,ft2,dyn + fcvt.q.d ft1,ft2,dyn + fcvt.d.w ft1,t0,dyn + fcvt.d.wu ft1,t0,dyn + fcvt.q.w ft1,t0,dyn + fcvt.q.wu ft1,t0,dyn + + # Different error message because of an invalid rounding mode + fcvt.q.wu ft1,t0,unknown diff --git a/gas/testsuite/gas/riscv/rounding-fcvt.q.l-noalias.d b/gas/testsuite/gas/riscv/rounding-fcvt.q.l-noalias.d new file mode 100644 index 000000000000..6f7a10f6c755 --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-fcvt.q.l-noalias.d @@ -0,0 +1,15 @@ +#as: -march=rv64ifdq +#source: rounding-fcvt.q.l.s +#warning_output: rounding-fcvt.q.l.l +#objdump: -d -M no-aliases + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <target>: +[ ]+[0-9a-f]+:[ ]+d62280d3[ ]+fcvt\.q\.l[ ]+ft1,t0 +[ ]+[0-9a-f]+:[ ]+d622f0d3[ ]+fcvt\.q\.l[ ]+ft1,t0,dyn +[ ]+[0-9a-f]+:[ ]+d63280d3[ ]+fcvt\.q\.lu[ ]+ft1,t0 +[ ]+[0-9a-f]+:[ ]+d632f0d3[ ]+fcvt\.q\.lu[ ]+ft1,t0,dyn diff --git a/gas/testsuite/gas/riscv/rounding-fcvt.q.l.d b/gas/testsuite/gas/riscv/rounding-fcvt.q.l.d new file mode 100644 index 000000000000..80b6320e873f --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-fcvt.q.l.d @@ -0,0 +1,15 @@ +#as: -march=rv64ifdq +#source: rounding-fcvt.q.l.s +#warning_output: rounding-fcvt.q.l.l +#objdump: -d + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <target>: +[ ]+[0-9a-f]+:[ ]+d62280d3[ ]+fcvt\.q\.l[ ]+ft1,t0 +[ ]+[0-9a-f]+:[ ]+d622f0d3[ ]+fcvt\.q\.l[ ]+ft1,t0 +[ ]+[0-9a-f]+:[ ]+d63280d3[ ]+fcvt\.q\.lu[ ]+ft1,t0 +[ ]+[0-9a-f]+:[ ]+d632f0d3[ ]+fcvt\.q\.lu[ ]+ft1,t0 diff --git a/gas/testsuite/gas/riscv/rounding-fcvt.q.l.l b/gas/testsuite/gas/riscv/rounding-fcvt.q.l.l new file mode 100644 index 000000000000..22df262891e8 --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-fcvt.q.l.l @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*: Warning: specifying a rounding mode is strongly discourged on widening conversion +.*: Warning: specifying a rounding mode is strongly discourged on widening conversion diff --git a/gas/testsuite/gas/riscv/rounding-fcvt.q.l.s b/gas/testsuite/gas/riscv/rounding-fcvt.q.l.s new file mode 100644 index 000000000000..ec60e53f7ad1 --- /dev/null +++ b/gas/testsuite/gas/riscv/rounding-fcvt.q.l.s @@ -0,0 +1,5 @@ +target: + fcvt.q.l ft1,t0 + fcvt.q.l ft1,t0,dyn + fcvt.q.lu ft1,t0 + fcvt.q.lu ft1,t0,dyn diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 1e6716e8e58c..e4d966a118df 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -592,6 +592,27 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info goto undefined_modifier; } break; + case 'f': + switch (*++oparg) + { + case 'M': /* Fall through. */ + case 'm': + /* Optional rounding mode (widening conversion) + which defaults to RNE (0b000). + Display non-default rounding mode if: + 1. rounding mode is invalid or + 2. 'no-aliases' option is specified. */ + if (EXTRACT_OPERAND (RM, l) == 0 + || (!no_aliases && riscv_rm[EXTRACT_OPERAND (RM, l)])) + break; + print (info->stream, dis_style_text, ","); + arg_print (info, EXTRACT_OPERAND (RM, l), riscv_rm, + ARRAY_SIZE (riscv_rm)); + break; + default: + goto undefined_modifier; + } + break; default: goto undefined_modifier; } @@ -640,6 +661,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info } } break; + default: undefined_modifier: /* xgettext:c-format */ diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 653eb60f2a58..dbfb4f3918b2 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -659,9 +659,9 @@ const struct riscv_opcode riscv_opcodes[] = {"fcvt.h.w", 0, INSN_CLASS_ZFH_INX, "D,s,m", MATCH_FCVT_H_W, MASK_FCVT_H_W, match_opcode, 0 }, {"fcvt.h.wu", 0, INSN_CLASS_ZFH_INX, "D,s", MATCH_FCVT_H_WU|MASK_RM, MASK_FCVT_H_WU|MASK_RM, match_opcode, 0 }, {"fcvt.h.wu", 0, INSN_CLASS_ZFH_INX, "D,s,m", MATCH_FCVT_H_WU, MASK_FCVT_H_WU, match_opcode, 0 }, -{"fcvt.s.h", 0, INSN_CLASS_ZFHMIN_INX, "D,S", MATCH_FCVT_S_H, MASK_FCVT_S_H|MASK_RM, match_opcode, 0 }, -{"fcvt.d.h", 0, INSN_CLASS_ZFHMIN_AND_D_INX, "D,S", MATCH_FCVT_D_H, MASK_FCVT_D_H|MASK_RM, match_opcode, 0 }, -{"fcvt.q.h", 0, INSN_CLASS_ZFHMIN_AND_Q_INX, "D,S", MATCH_FCVT_Q_H, MASK_FCVT_Q_H|MASK_RM, match_opcode, 0 }, +{"fcvt.s.h", 0, INSN_CLASS_ZFHMIN_INX, "D,SWfM", MATCH_FCVT_S_H, MASK_FCVT_S_H, match_opcode, 0 }, +{"fcvt.d.h", 0, INSN_CLASS_ZFHMIN_AND_D_INX, "D,SWfM", MATCH_FCVT_D_H, MASK_FCVT_D_H, match_opcode, 0 }, +{"fcvt.q.h", 0, INSN_CLASS_ZFHMIN_AND_Q_INX, "D,SWfM", MATCH_FCVT_Q_H, MASK_FCVT_Q_H, match_opcode, 0 }, {"fcvt.h.s", 0, INSN_CLASS_ZFHMIN_INX, "D,S", MATCH_FCVT_H_S|MASK_RM, MASK_FCVT_H_S|MASK_RM, match_opcode, 0 }, {"fcvt.h.s", 0, INSN_CLASS_ZFHMIN_INX, "D,S,m", MATCH_FCVT_H_S, MASK_FCVT_H_S, match_opcode, 0 }, {"fcvt.h.d", 0, INSN_CLASS_ZFHMIN_AND_D_INX, "D,S", MATCH_FCVT_H_D|MASK_RM, MASK_FCVT_H_D|MASK_RM, match_opcode, 0 }, @@ -800,9 +800,9 @@ const struct riscv_opcode riscv_opcodes[] = {"fcvt.w.d", 0, INSN_CLASS_D_INX, "d,S,m", MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, 0 }, {"fcvt.wu.d", 0, INSN_CLASS_D_INX, "d,S", MATCH_FCVT_WU_D|MASK_RM, MASK_FCVT_WU_D|MASK_RM, match_opcode, 0 }, {"fcvt.wu.d", 0, INSN_CLASS_D_INX, "d,S,m", MATCH_FCVT_WU_D, MASK_FCVT_WU_D, match_opcode, 0 }, -{"fcvt.d.w", 0, INSN_CLASS_D_INX, "D,s", MATCH_FCVT_D_W, MASK_FCVT_D_W|MASK_RM, match_opcode, 0 }, -{"fcvt.d.wu", 0, INSN_CLASS_D_INX, "D,s", MATCH_FCVT_D_WU, MASK_FCVT_D_WU|MASK_RM, match_opcode, 0 }, -{"fcvt.d.s", 0, INSN_CLASS_D_INX, "D,S", MATCH_FCVT_D_S, MASK_FCVT_D_S|MASK_RM, match_opcode, 0 }, +{"fcvt.d.w", 0, INSN_CLASS_D_INX, "D,sWfM", MATCH_FCVT_D_W, MASK_FCVT_D_W, match_opcode, 0 }, +{"fcvt.d.wu", 0, INSN_CLASS_D_INX, "D,sWfM", MATCH_FCVT_D_WU, MASK_FCVT_D_WU, match_opcode, 0 }, +{"fcvt.d.s", 0, INSN_CLASS_D_INX, "D,SWfM", MATCH_FCVT_D_S, MASK_FCVT_D_S, match_opcode, 0 }, {"fcvt.s.d", 0, INSN_CLASS_D_INX, "D,S", MATCH_FCVT_S_D|MASK_RM, MASK_FCVT_S_D|MASK_RM, match_opcode, 0 }, {"fcvt.s.d", 0, INSN_CLASS_D_INX, "D,S,m", MATCH_FCVT_S_D, MASK_FCVT_S_D, match_opcode, 0 }, {"fclass.d", 0, INSN_CLASS_D_INX, "d,S", MATCH_FCLASS_D, MASK_FCLASS_D, match_opcode, 0 }, @@ -857,10 +857,10 @@ const struct riscv_opcode riscv_opcodes[] = {"fcvt.w.q", 0, INSN_CLASS_Q_INX, "d,S,m", MATCH_FCVT_W_Q, MASK_FCVT_W_Q, match_opcode, 0 }, {"fcvt.wu.q", 0, INSN_CLASS_Q_INX, "d,S", MATCH_FCVT_WU_Q|MASK_RM, MASK_FCVT_WU_Q|MASK_RM, match_opcode, 0 }, {"fcvt.wu.q", 0, INSN_CLASS_Q_INX, "d,S,m", MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q, match_opcode, 0 }, -{"fcvt.q.w", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_W, MASK_FCVT_Q_W|MASK_RM, match_opcode, 0 }, -{"fcvt.q.wu", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU|MASK_RM, match_opcode, 0 }, -{"fcvt.q.s", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_Q_S, MASK_FCVT_Q_S|MASK_RM, match_opcode, 0 }, -{"fcvt.q.d", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_Q_D, MASK_FCVT_Q_D|MASK_RM, match_opcode, 0 }, +{"fcvt.q.w", 0, INSN_CLASS_Q_INX, "D,sWfM", MATCH_FCVT_Q_W, MASK_FCVT_Q_W, match_opcode, 0 }, +{"fcvt.q.wu", 0, INSN_CLASS_Q_INX, "D,sWfM", MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU, match_opcode, 0 }, +{"fcvt.q.s", 0, INSN_CLASS_Q_INX, "D,SWfM", MATCH_FCVT_Q_S, MASK_FCVT_Q_S, match_opcode, 0 }, +{"fcvt.q.d", 0, INSN_CLASS_Q_INX, "D,SWfM", MATCH_FCVT_Q_D, MASK_FCVT_Q_D, match_opcode, 0 }, {"fcvt.s.q", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_S_Q|MASK_RM, MASK_FCVT_S_Q|MASK_RM, match_opcode, 0 }, {"fcvt.s.q", 0, INSN_CLASS_Q_INX, "D,S,m", MATCH_FCVT_S_Q, MASK_FCVT_S_Q, match_opcode, 0 }, {"fcvt.d.q", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_D_Q|MASK_RM, MASK_FCVT_D_Q|MASK_RM, match_opcode, 0 }, @@ -875,10 +875,8 @@ const struct riscv_opcode riscv_opcodes[] = {"fcvt.l.q", 64, INSN_CLASS_Q_INX, "d,S,m", MATCH_FCVT_L_Q, MASK_FCVT_L_Q, match_opcode, 0 }, {"fcvt.lu.q", 64, INSN_CLASS_Q_INX, "d,S", MATCH_FCVT_LU_Q|MASK_RM, MASK_FCVT_LU_Q|MASK_RM, match_opcode, 0 }, {"fcvt.lu.q", 64, INSN_CLASS_Q_INX, "d,S,m", MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q, match_opcode, 0 }, -{"fcvt.q.l", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_L, MASK_FCVT_Q_L|MASK_RM, match_opcode, 0 }, -{"fcvt.q.l", 64, INSN_CLASS_Q_INX, "D,s,m", MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 }, -{"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 }, -{"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,s,m", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 }, +{"fcvt.q.l", 64, INSN_CLASS_Q_INX, "D,sWfm", MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 }, +{"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,sWfm", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 }, /* Compressed instructions. */ {"c.unimp", 0, INSN_CLASS_C, "", 0, 0xffffU, match_opcode, 0 }, -- 2.38.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-11-29 3:19 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-11-28 6:39 [PATCH 0/3] RISC-V: Support non-standard encodings (on widening FP ops) Tsukasa OI 2022-11-28 6:39 ` [PATCH 1/3] RISC-V: Allocate "various" operand type Tsukasa OI 2022-11-29 2:42 ` Nelson Chu 2022-11-29 3:19 ` Tsukasa OI 2022-11-28 6:39 ` [PATCH 2/3] RISC-V: Reorganize invalid rounding mode test Tsukasa OI 2022-11-28 6:39 ` [PATCH 3/3] RISC-V: Rounding mode on widening instructions Tsukasa OI
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).