Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disassembler: Rounding mode on widening instructions #2

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,15 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
goto unknown_validate_operand;
}
break;
case '!': /* Special handlings. */
switch (*++oparg)
{
case 'M': /* Fall through. */
case 'm': USE_BITS (OP_MASK_RM, OP_SH_RM); break;
default:
goto unknown_validate_operand;
}
break;
default:
unknown_validate_operand:
as_bad (_("internal: bad RISC-V opcode "
Expand Down Expand Up @@ -3265,6 +3274,40 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
asarg = expr_end;
continue;

case '!': /* Special handlings. */
switch (*++oparg)
{
case 'M':
case 'm':
/* Optional rounding mode (widening conversion)
'M': operand either disallowed or not recommended
(considered to be non-useful to regular 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), &regno))
{
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:
unknown_riscv_ip_operand:
as_fatal (_("internal: unknown argument type `%s'"),
Expand Down
3 changes: 0 additions & 3 deletions gas/testsuite/gas/riscv/rouding-fail.d

This file was deleted.

3 changes: 0 additions & 3 deletions gas/testsuite/gas/riscv/rouding-fail.s

This file was deleted.

12 changes: 12 additions & 0 deletions gas/testsuite/gas/riscv/rounding-dis-widening-noalias.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#as: -march=rv64ifd
#source: rounding-dis-widening.s
#objdump: -dr -M no-aliases

.*:[ ]+file format .*


Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+420100d3[ ]+fcvt\.d\.s[ ]+ft1,ft2
[ ]+[0-9a-f]+:[ ]+420170d3[ ]+fcvt\.d\.s[ ]+ft1,ft2,dyn
12 changes: 12 additions & 0 deletions gas/testsuite/gas/riscv/rounding-dis-widening.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#as: -march=rv64ifd
#source: rounding-dis-widening.s
#objdump: -dr

.*:[ ]+file format .*


Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+420100d3[ ]+fcvt\.d\.s[ ]+ft1,ft2
[ ]+[0-9a-f]+:[ ]+420170d3[ ]+fcvt\.d\.s[ ]+ft1,ft2
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/rounding-dis-widening.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target:
fcvt.d.s ft1,ft2
.insn 0x420170d3
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fail-invalid.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv32ifd
#source: rounding-fail-invalid.s
#error_output: rounding-fail-invalid.l
Original file line number Diff line number Diff line change
@@ -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'
5 changes: 5 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fail-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
target:
fadd.s fa1,fa1,fa1,
fadd.d fa1,fa1,fa1,
fadd.s fa1,fa1,fa1,unknown
fadd.d fa1,fa1,fa1,unknown
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fail-widening.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv64ifdq_zfh
#source: rounding-fail-widening.s
#error_output: rounding-fail-widening.l
12 changes: 12 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fail-widening.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.*: Assembler messages:
.*: 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'
13 changes: 13 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fail-widening.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
target:
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
15 changes: 15 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fcvt.q.l-noalias.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#as: -march=rv64ifdq
#source: rounding-fcvt.q.l.s
#warning_output: rounding-fcvt.q.l.l
#objdump: -dr -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
15 changes: 15 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fcvt.q.l.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#as: -march=rv64ifdq
#source: rounding-fcvt.q.l.s
#warning_output: rounding-fcvt.q.l.l
#objdump: -dr

.*:[ ]+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
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fcvt.q.l.l
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fcvt.q.l.s
Original file line number Diff line number Diff line change
@@ -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
16 changes: 16 additions & 0 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,22 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
print (info->stream, dis_style_text, "%d", rs1);
break;

case '!': /* Special handlings. */
switch (*++oparg)
{
case 'M': /* Fall through. */
case 'm':
/* Optional rounding mode (widening conversion)
which defaults to RNE (0b000). */
if (!no_aliases || EXTRACT_OPERAND (RM, l) == 0)
break;
print (info->stream, dis_style_text, ",");
arg_print (info, EXTRACT_OPERAND (RM, l), riscv_rm,
ARRAY_SIZE (riscv_rm));
break;
}
break;

default:
/* xgettext:c-format */
print (info->stream, dis_style_text,
Expand Down
26 changes: 12 additions & 14 deletions opcodes/riscv-opc.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,9 +611,9 @@ const struct riscv_opcode riscv_opcodes[] =
{"fcvt.h.w", 0, INSN_CLASS_ZFH_OR_ZHINX, "D,s,m", MATCH_FCVT_H_W, MASK_FCVT_H_W, match_opcode, 0 },
{"fcvt.h.wu", 0, INSN_CLASS_ZFH_OR_ZHINX, "D,s", MATCH_FCVT_H_WU|MASK_RM, MASK_FCVT_H_WU|MASK_RM, match_opcode, 0 },
{"fcvt.h.wu", 0, INSN_CLASS_ZFH_OR_ZHINX, "D,s,m", MATCH_FCVT_H_WU, MASK_FCVT_H_WU, match_opcode, 0 },
{"fcvt.s.h", 0, INSN_CLASS_ZFH_OR_ZHINX, "D,S", MATCH_FCVT_S_H, MASK_FCVT_S_H|MASK_RM, match_opcode, 0 },
{"fcvt.d.h", 0, INSN_CLASS_D_AND_ZFH_INX, "D,S", MATCH_FCVT_D_H, MASK_FCVT_D_H|MASK_RM, match_opcode, 0 },
{"fcvt.q.h", 0, INSN_CLASS_Q_AND_ZFH_INX, "D,S", MATCH_FCVT_Q_H, MASK_FCVT_Q_H|MASK_RM, match_opcode, 0 },
{"fcvt.s.h", 0, INSN_CLASS_ZFH_OR_ZHINX, "D,S!M", MATCH_FCVT_S_H, MASK_FCVT_S_H, match_opcode, 0 },
{"fcvt.d.h", 0, INSN_CLASS_D_AND_ZFH_INX, "D,S!M", MATCH_FCVT_D_H, MASK_FCVT_D_H, match_opcode, 0 },
{"fcvt.q.h", 0, INSN_CLASS_Q_AND_ZFH_INX, "D,S!M", MATCH_FCVT_Q_H, MASK_FCVT_Q_H, match_opcode, 0 },
{"fcvt.h.s", 0, INSN_CLASS_ZFH_OR_ZHINX, "D,S", MATCH_FCVT_H_S|MASK_RM, MASK_FCVT_H_S|MASK_RM, match_opcode, 0 },
{"fcvt.h.s", 0, INSN_CLASS_ZFH_OR_ZHINX, "D,S,m", MATCH_FCVT_H_S, MASK_FCVT_H_S, match_opcode, 0 },
{"fcvt.h.d", 0, INSN_CLASS_D_AND_ZFH_INX, "D,S", MATCH_FCVT_H_D|MASK_RM, MASK_FCVT_H_D|MASK_RM, match_opcode, 0 },
Expand Down Expand Up @@ -754,9 +754,9 @@ const struct riscv_opcode riscv_opcodes[] =
{"fcvt.w.d", 0, INSN_CLASS_D_OR_ZDINX, "d,S,m", MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, 0 },
{"fcvt.wu.d", 0, INSN_CLASS_D_OR_ZDINX, "d,S", MATCH_FCVT_WU_D|MASK_RM, MASK_FCVT_WU_D|MASK_RM, match_opcode, 0 },
{"fcvt.wu.d", 0, INSN_CLASS_D_OR_ZDINX, "d,S,m", MATCH_FCVT_WU_D, MASK_FCVT_WU_D, match_opcode, 0 },
{"fcvt.d.w", 0, INSN_CLASS_D_OR_ZDINX, "D,s", MATCH_FCVT_D_W, MASK_FCVT_D_W|MASK_RM, match_opcode, 0 },
{"fcvt.d.wu", 0, INSN_CLASS_D_OR_ZDINX, "D,s", MATCH_FCVT_D_WU, MASK_FCVT_D_WU|MASK_RM, match_opcode, 0 },
{"fcvt.d.s", 0, INSN_CLASS_D_OR_ZDINX, "D,S", MATCH_FCVT_D_S, MASK_FCVT_D_S|MASK_RM, match_opcode, 0 },
{"fcvt.d.w", 0, INSN_CLASS_D_OR_ZDINX, "D,s!M", MATCH_FCVT_D_W, MASK_FCVT_D_W, match_opcode, 0 },
{"fcvt.d.wu", 0, INSN_CLASS_D_OR_ZDINX, "D,s!M", MATCH_FCVT_D_WU, MASK_FCVT_D_WU, match_opcode, 0 },
{"fcvt.d.s", 0, INSN_CLASS_D_OR_ZDINX, "D,S!M", MATCH_FCVT_D_S, MASK_FCVT_D_S, match_opcode, 0 },
{"fcvt.s.d", 0, INSN_CLASS_D_OR_ZDINX, "D,S", MATCH_FCVT_S_D|MASK_RM, MASK_FCVT_S_D|MASK_RM, match_opcode, 0 },
{"fcvt.s.d", 0, INSN_CLASS_D_OR_ZDINX, "D,S,m", MATCH_FCVT_S_D, MASK_FCVT_S_D, match_opcode, 0 },
{"fclass.d", 0, INSN_CLASS_D_OR_ZDINX, "d,S", MATCH_FCLASS_D, MASK_FCLASS_D, match_opcode, 0 },
Expand Down Expand Up @@ -811,10 +811,10 @@ const struct riscv_opcode riscv_opcodes[] =
{"fcvt.w.q", 0, INSN_CLASS_Q_OR_ZQINX, "d,S,m", MATCH_FCVT_W_Q, MASK_FCVT_W_Q, match_opcode, 0 },
{"fcvt.wu.q", 0, INSN_CLASS_Q_OR_ZQINX, "d,S", MATCH_FCVT_WU_Q|MASK_RM, MASK_FCVT_WU_Q|MASK_RM, match_opcode, 0 },
{"fcvt.wu.q", 0, INSN_CLASS_Q_OR_ZQINX, "d,S,m", MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q, match_opcode, 0 },
{"fcvt.q.w", 0, INSN_CLASS_Q_OR_ZQINX, "D,s", MATCH_FCVT_Q_W, MASK_FCVT_Q_W|MASK_RM, match_opcode, 0 },
{"fcvt.q.wu", 0, INSN_CLASS_Q_OR_ZQINX, "D,s", MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU|MASK_RM, match_opcode, 0 },
{"fcvt.q.s", 0, INSN_CLASS_Q_OR_ZQINX, "D,S", MATCH_FCVT_Q_S, MASK_FCVT_Q_S|MASK_RM, match_opcode, 0 },
{"fcvt.q.d", 0, INSN_CLASS_Q_OR_ZQINX, "D,S", MATCH_FCVT_Q_D, MASK_FCVT_Q_D|MASK_RM, match_opcode, 0 },
{"fcvt.q.w", 0, INSN_CLASS_Q_OR_ZQINX, "D,s!M", MATCH_FCVT_Q_W, MASK_FCVT_Q_W, match_opcode, 0 },
{"fcvt.q.wu", 0, INSN_CLASS_Q_OR_ZQINX, "D,s!M", MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU, match_opcode, 0 },
{"fcvt.q.s", 0, INSN_CLASS_Q_OR_ZQINX, "D,S!M", MATCH_FCVT_Q_S, MASK_FCVT_Q_S, match_opcode, 0 },
{"fcvt.q.d", 0, INSN_CLASS_Q_OR_ZQINX, "D,S!M", MATCH_FCVT_Q_D, MASK_FCVT_Q_D, match_opcode, 0 },
{"fcvt.s.q", 0, INSN_CLASS_Q_OR_ZQINX, "D,S", MATCH_FCVT_S_Q|MASK_RM, MASK_FCVT_S_Q|MASK_RM, match_opcode, 0 },
{"fcvt.s.q", 0, INSN_CLASS_Q_OR_ZQINX, "D,S,m", MATCH_FCVT_S_Q, MASK_FCVT_S_Q, match_opcode, 0 },
{"fcvt.d.q", 0, INSN_CLASS_Q_OR_ZQINX, "D,S", MATCH_FCVT_D_Q|MASK_RM, MASK_FCVT_D_Q|MASK_RM, match_opcode, 0 },
Expand All @@ -829,10 +829,8 @@ const struct riscv_opcode riscv_opcodes[] =
{"fcvt.l.q", 64, INSN_CLASS_Q_OR_ZQINX, "d,S,m", MATCH_FCVT_L_Q, MASK_FCVT_L_Q, match_opcode, 0 },
{"fcvt.lu.q", 64, INSN_CLASS_Q_OR_ZQINX, "d,S", MATCH_FCVT_LU_Q|MASK_RM, MASK_FCVT_LU_Q|MASK_RM, match_opcode, 0 },
{"fcvt.lu.q", 64, INSN_CLASS_Q_OR_ZQINX, "d,S,m", MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q, match_opcode, 0 },
{"fcvt.q.l", 64, INSN_CLASS_Q_OR_ZQINX, "D,s", MATCH_FCVT_Q_L, MASK_FCVT_Q_L|MASK_RM, match_opcode, 0 },
{"fcvt.q.l", 64, INSN_CLASS_Q_OR_ZQINX, "D,s,m", MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
{"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX, "D,s", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
{"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX, "D,s,m", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
{"fcvt.q.l", 64, INSN_CLASS_Q_OR_ZQINX, "D,s!m", MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
{"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX, "D,s!m", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },

/* Compressed instructions. */
{"c.unimp", 0, INSN_CLASS_C, "", 0, 0xffffU, match_opcode, 0 },
Expand Down