From 1c2e813f2abb2e2394441169d94db3145ce7d8aa Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Wed, 6 Jul 2022 12:06:01 +0900 Subject: [PATCH] RISC-V: Non-standard encodings of `fence' (disasm) 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. * riscv-opc.c (riscv_opcodes): Reorder `fence.tso' so that reserved `fence' instruction entry is matched at the end. Ignore reserved bit positions. --- gas/config/tc-riscv.c | 3 +++ gas/testsuite/gas/riscv/fence-dis-nonstd.d | 20 ++++++++++++++++++++ gas/testsuite/gas/riscv/fence-dis-nonstd.s | 20 ++++++++++++++++++++ include/opcode/riscv.h | 2 ++ opcodes/riscv-opc.c | 4 ++-- 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 gas/testsuite/gas/riscv/fence-dis-nonstd.d create mode 100644 gas/testsuite/gas/riscv/fence-dis-nonstd.s diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index d1d936e31f0..d6aba9596c0 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -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; } @@ -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; diff --git a/gas/testsuite/gas/riscv/fence-dis-nonstd.d b/gas/testsuite/gas/riscv/fence-dis-nonstd.d new file mode 100644 index 00000000000..dabfc943a14 --- /dev/null +++ b/gas/testsuite/gas/riscv/fence-dis-nonstd.d @@ -0,0 +1,20 @@ +#as: -march=rv32i +#source: fence-dis-nonstd.s +#objdump: -dr + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 : +[ ]+[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]+:[ ]+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 diff --git a/gas/testsuite/gas/riscv/fence-dis-nonstd.s b/gas/testsuite/gas/riscv/fence-dis-nonstd.s new file mode 100644 index 00000000000..19fa93a22fc --- /dev/null +++ b/gas/testsuite/gas/riscv/fence-dis-nonstd.s @@ -0,0 +1,20 @@ +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 + # 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 diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index b115e338a05..b2283f3b332 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -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 diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 50d081bdf38..03ca1a478ff 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -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 },