Skip to content
Open
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
29 changes: 29 additions & 0 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,8 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
case 'f':
switch (*++oparg)
{
case 'M': /* Fall through. */
case 'm': USE_BITS (OP_MASK_RM, OP_SH_RM); break;
case 'v': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
default:
goto unknown_validate_operand;
Expand Down Expand Up @@ -3526,6 +3528,33 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
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), &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;
case 'v':
/* FLI.[HSDQ] value field for 'Zfa' extension. */
if (!arg_lookup (&asarg, riscv_fli_symval,
Expand Down
13 changes: 13 additions & 0 deletions gas/testsuite/gas/riscv/rounding-dis-widening-na.d
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions gas/testsuite/gas/riscv/rounding-dis-widening.d
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions gas/testsuite/gas/riscv/rounding-dis-widening.s
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion gas/testsuite/gas/riscv/rounding-fail.d
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#as: -march=rv32ifd
#as: -march=rv32ifdq_zfh
#source: rounding-fail.s
#error_output: rounding-fail.l
13 changes: 13 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fail.l
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
.*: 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'
.*: 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'
20 changes: 20 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fail.s
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
target:
# Empty rounding mode
fadd.s fa1,fa1,fa1,
fadd.d fa1,fa1,fa1,
# Invalid rounding mode
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
15 changes: 15 additions & 0 deletions gas/testsuite/gas/riscv/rounding-fcvt.q.l-na.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: -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
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: -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
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
14 changes: 14 additions & 0 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,20 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
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;
case 'v':
if (riscv_fli_symval[rs1])
print (info->stream, dis_style_text, "%s",
Expand Down
26 changes: 12 additions & 14 deletions opcodes/riscv-opc.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,9 +702,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 },
Expand Down Expand Up @@ -843,9 +843,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 },
Expand Down Expand Up @@ -900,10 +900,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 },
Expand All @@ -918,10 +918,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 },
Expand Down