Skip to content

Commit

Permalink
RISC-V: Non-standard encodings of `fence' (disasm)
Browse files Browse the repository at this point in the history
This commit adds disassembler support for non-standard encodings of the
`fence' instruction.  Despite that those fields are reserved in many
cases, base implementation shall ignore and handle with fm=0000.

gas/ChangeLog:

	* config/tc-riscv.c (validate_riscv_insn): Add ignored fm field.
	(riscv_ip): Add ignored fm field.
	* testsuite/gas/riscv/fence-dis-nonstd.s: New disasm test.
	* testsuite/gas/riscv/fence-dis-nonstd.d: Likewise.

include/ChangeLog:

	* opcode/riscv.h (OP_MASK_FM, OP_SH_FM): New.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Add ignored fm field.  Print
	"none" on fence pred/succ operand value 0b0000.
	(arg_print): Add default value argument.
	* riscv-opc.c (riscv_opcodes): Reorder `fence.tso' so that reserved
	`fence' instruction entry is matched at the end.  Ignore reserved
	bit positions.
  • Loading branch information
a4lg committed Jul 26, 2022
1 parent 3edabf5 commit d020e3c
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 8 deletions.
3 changes: 3 additions & 0 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,8 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
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;
/* fence: fm field. */
case 'f': USE_BITS (OP_MASK_FM, OP_SH_FM); break;
default:
goto unknown_validate_operand;
}
Expand Down Expand Up @@ -3296,6 +3298,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
case 'd': /* Ignored RD. */
case 's': /* Ignored RS1. */
case 'j': /* Ignored immediate (I-type). */
case 'f': /* Ignored fence fm field. */
break;
default:
goto unknown_riscv_ip_operand;
Expand Down
21 changes: 21 additions & 0 deletions gas/testsuite/gas/riscv/fence-dis-nonstd.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#as: -march=rv32i
#source: fence-dis-nonstd.s
#objdump: -dr

.*:[ ]+file format .*


Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+0ff0000f[ ]+fence
[ ]+[0-9a-f]+:[ ]+8330000f[ ]+fence\.tso
[ ]+[0-9a-f]+:[ ]+0ff0000f[ ]+fence
[ ]+[0-9a-f]+:[ ]+8330000f[ ]+fence\.tso
[ ]+[0-9a-f]+:[ ]+0100000f[ ]+fence[ ]+w,none
[ ]+[0-9a-f]+:[ ]+0cf00f8f[ ]+fence[ ]+io,iorw
[ ]+[0-9a-f]+:[ ]+0fcf800f[ ]+fence[ ]+iorw,io
[ ]+[0-9a-f]+:[ ]+83300f8f[ ]+fence\.tso
[ ]+[0-9a-f]+:[ ]+833f800f[ ]+fence\.tso
[ ]+[0-9a-f]+:[ ]+8ff0000f[ ]+fence[ ]+iorw,iorw
[ ]+[0-9a-f]+:[ ]+1330000f[ ]+fence[ ]+rw,rw
22 changes: 22 additions & 0 deletions gas/testsuite/gas/riscv/fence-dis-nonstd.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
target:
fence
fence.tso
# Standard encodings of fence and fence.tso
.insn i MISC_MEM, 0, x0, x0, 0x0ff
.insn i MISC_MEM, 0, x0, x0, 0x833-0x1000
# Standard encoding of pause
.insn i MISC_MEM, 0, x0, x0, 0x010
# Non-standard encodings (regular, either RD or RS1 are non-zero)
# Ignore unused bit fields.
.insn i MISC_MEM, 0, x31, x0, 0x0cf
.insn i MISC_MEM, 0, x0, x31, 0x0fc
# Non-standard encodings (TSO, either RD or RS1 are non-zero)
# Ignore unused bit fields for fence.tso.
.insn i MISC_MEM, 0, x31, x0, 0x833-0x1000
.insn i MISC_MEM, 0, x0, x31, 0x833-0x1000
# Non-standard encoding (TSO, pred and succ are not defined)
# Since fm+pred+succ is not defined, fallback to regular fence.
.insn i MISC_MEM, 0, x0, x0, 0x8ff-0x1000
# Non-standard encoding (fm is reserved)
# Fallback to regular fence.
.insn i MISC_MEM, 0, x0, x0, 0x133
2 changes: 2 additions & 0 deletions include/opcode/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ static const char * const riscv_pred_succ[16] =
#define OP_SH_AQ 26
#define OP_MASK_RL 0x1
#define OP_SH_RL 25
#define OP_MASK_FM 0xfU
#define OP_SH_FM 28

#define OP_MASK_CSR 0xfffU
#define OP_SH_CSR 20
Expand Down
14 changes: 8 additions & 6 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,11 @@ parse_riscv_dis_options (const char *opts_in)

static void
arg_print (struct disassemble_info *info, unsigned long val,
const char* const* array, size_t size)
const char *const *array, size_t size, const char *default_val)
{
const char *s = val >= size || array[val] == NULL ? "unknown" : array[val];
const char *s = val >= size || array[val] == NULL
? (default_val == NULL ? "unknown" : default_val)
: array[val];
(*info->fprintf_styled_func) (info->stream, dis_style_text, "%s", s);
}

Expand Down Expand Up @@ -414,17 +416,17 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info

case 'm':
arg_print (info, EXTRACT_OPERAND (RM, l),
riscv_rm, ARRAY_SIZE (riscv_rm));
riscv_rm, ARRAY_SIZE (riscv_rm), NULL);
break;

case 'P':
arg_print (info, EXTRACT_OPERAND (PRED, l),
riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ));
riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ), "none");
break;

case 'Q':
arg_print (info, EXTRACT_OPERAND (SUCC, l),
riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ));
riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ), "none");
break;

case 'o':
Expand Down Expand Up @@ -569,7 +571,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
break;
print (info->stream, dis_style_text, ",");
arg_print (info, EXTRACT_OPERAND (RM, l), riscv_rm,
ARRAY_SIZE (riscv_rm));
ARRAY_SIZE (riscv_rm), NULL);
break;
}
break;
Expand Down
4 changes: 2 additions & 2 deletions opcodes/riscv-opc.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,10 @@ const struct riscv_opcode riscv_opcodes[] =
{"sw", 0, INSN_CLASS_I, "t,q(s)", MATCH_SW, MASK_SW, match_opcode, INSN_DREF|INSN_4_BYTE },
{"sw", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_SW, match_never, INSN_MACRO },
{"pause", 0, INSN_CLASS_ZIHINTPAUSE, "",MATCH_PAUSE, MASK_PAUSE, match_opcode, 0 },
{"fence.tso", 0, INSN_CLASS_I, "~ds", MATCH_FENCE_TSO, MASK_FENCE_TSO, match_opcode, 0 },
{"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", 0, INSN_CLASS_I, "P,Q~dsf", MATCH_FENCE, MASK_FENCE, 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, INSN_ALIAS },
{"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 },
{"rdtime", 0, INSN_CLASS_I, "d", MATCH_RDTIME, MASK_RDTIME, match_opcode, INSN_ALIAS },
Expand Down

0 comments on commit d020e3c

Please sign in to comment.