Skip to content

Commit

Permalink
RISC-V: Non-standard encodings of fence.i (disasm)
Browse files Browse the repository at this point in the history
This commit adds disassembler support for non-standard encodings of the
fence.i instruction.  Those fields are supposed to be zero but base
implementation shall ignore those fields.

gas/ChangeLog:

	* config/tc-riscv.c (validate_riscv_insn): Add ignored bit fields.
	(riscv_ip): Add support for ignored bit fields.
	* testsuite/gas/riscv/zifencei-dis-nonstd.s: New disasm test.
	* testsuite/gas/riscv/zifencei-dis-nonstd.d: Likewise.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Add support for ignored bit
	fields.
	* riscv-opc.c (riscv_opcodes): Ignore RD/RS1/immediate (I-type)
	fields on the fence.i instruction.
  • Loading branch information
a4lg committed Nov 19, 2022
1 parent 3e7f83d commit 6f9dcf7
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
30 changes: 30 additions & 0 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,20 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
}
}
break;
case '\\': /* Ignored fields (w/o defaults). */
while (*++oparg)
{
switch (*oparg)
{
case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
default:
goto unknown_validate_operand;
}
}
--oparg;
break;
default:
unknown_validate_operand:
as_bad (_("internal: bad RISC-V opcode "
Expand Down Expand Up @@ -3512,6 +3526,22 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
}
break;

case '\\': /* Ignored fields (w/o defaults). */
while (*++oparg)
{
switch (*oparg)
{
case 'd': /* Ignored RD. */
case 's': /* Ignored RS1. */
case 'j': /* Ignored immediate (I-type). */
break;
default:
goto unknown_riscv_ip_operand;
}
}
--oparg;
continue;

default:
unknown_riscv_ip_operand:
as_fatal (_("internal: unknown argument type `%s'"),
Expand Down
15 changes: 15 additions & 0 deletions gas/testsuite/gas/riscv/zifencei-dis-nonstd.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#as: -march=rv32i_zifencei
#source: zifencei-dis-nonstd.s
#objdump: -dr

.*:[ ]+file format .*


Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+0000100f[ ]+fence\.i
[ ]+[0-9a-f]+:[ ]+0000100f[ ]+fence\.i
[ ]+[0-9a-f]+:[ ]+00001f8f[ ]+fence\.i
[ ]+[0-9a-f]+:[ ]+000f900f[ ]+fence\.i
[ ]+[0-9a-f]+:[ ]+fff0100f[ ]+fence\.i
8 changes: 8 additions & 0 deletions gas/testsuite/gas/riscv/zifencei-dis-nonstd.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
target:
fence.i
# Standard encoding of fence.i
.insn i MISC_MEM, 1, x0, x0, 0
# Following are non-standard encodings
.insn i MISC_MEM, 1, x31, x0, 0
.insn i MISC_MEM, 1, x0, x31, 0
.insn i MISC_MEM, 1, x0, x0, -1
10 changes: 7 additions & 3 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
fprintf_styled_ftype print = info->fprintf_styled_func;
const char *opargStart;

if (*oparg != '\0')
#define OPARG_IS_END(offset) (oparg[offset] == '\0' || oparg[offset] == '\\')
if (!OPARG_IS_END(0))
print (info->stream, dis_style_text, "\t");

for (; *oparg != '\0'; oparg++)
Expand Down Expand Up @@ -418,7 +419,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info

case '0':
/* Only print constant 0 if it is the last argument. */
if (!oparg[1])
if (OPARG_IS_END(1))
print (info->stream, dis_style_immediate, "0");
break;

Expand Down Expand Up @@ -629,7 +630,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
{
case 'l': /* Literal. */
oparg++;
while (*oparg && *oparg != ',')
while (!OPARG_IS_END(0) && *oparg != ',')
{
print (info->stream, dis_style_immediate, "%c", *oparg);
oparg++;
Expand Down Expand Up @@ -662,6 +663,9 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
}
break;

case '\\': /* Ignored fields. */
return;

default:
undefined_modifier:
/* xgettext:c-format */
Expand Down
2 changes: 1 addition & 1 deletion opcodes/riscv-opc.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ const struct riscv_opcode riscv_opcodes[] =
{"sw", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_SW, match_never, INSN_MACRO },
{"fence", 0, INSN_CLASS_I, "", MATCH_FENCE|MASK_PRED|MASK_SUCC, MASK_FENCE|MASK_RD|MASK_RS1|MASK_IMM, match_opcode, INSN_ALIAS },
{"fence", 0, INSN_CLASS_I, "P,Q", MATCH_FENCE, MASK_FENCE|MASK_RD|MASK_RS1|(MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
{"fence.i", 0, INSN_CLASS_ZIFENCEI, "", MATCH_FENCE_I, MASK_FENCE|MASK_RD|MASK_RS1|MASK_IMM, match_opcode, 0 },
{"fence.i", 0, INSN_CLASS_ZIFENCEI, "\\dsj", MATCH_FENCE_I, MASK_FENCE_I, match_opcode, 0 },
{"fence.tso", 0, INSN_CLASS_I, "", MATCH_FENCE_TSO, MASK_FENCE_TSO|MASK_RD|MASK_RS1, match_opcode, 0 },
{"rdcycle", 0, INSN_CLASS_I, "d", MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, INSN_ALIAS },
{"rdinstret", 0, INSN_CLASS_I, "d", MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, INSN_ALIAS },
Expand Down

0 comments on commit 6f9dcf7

Please sign in to comment.