From: Jens Remus <jremus@linux.ibm.com>
To: binutils@sourceware.org
Cc: Jens Remus <jremus@linux.ibm.com>,
Andreas Krebbel <krebbel@linux.ibm.com>,
Nick Clifton <nickc@redhat.com>
Subject: [PATCH v2 6/7] s390: Optionally print instruction description in disassembly
Date: Fri, 15 Dec 2023 15:36:15 +0100 [thread overview]
Message-ID: <20231215143616.820185-7-jremus@linux.ibm.com> (raw)
In-Reply-To: <20231215143616.820185-1-jremus@linux.ibm.com>
Print instruction description as comment in disassembly with s390
architecture specific option "insndesc":
- For objdump it can be enabled with option "-M insndesc"
- In gdb it can be enabled with "set disassembler-options insndesc"
Since comments are not column aligned the output can enhanced for
readability by postprocessing using a filter such as "expand":
... | expand -t 8,16,24,32,40,80
Or when using in combination with objdump option --visualize-jumps:
... | expand | sed -e 's/ *#/\t#/' | expand -t 1,80
Note that the instruction descriptions add about 128 KB to s390-opc.o:
s390-opc.o without instruction descriptions: 216368 bytes
s390-opc.o with instruction descriptions : 348432 bytes
binutils/
* NEWS: Mention new s390-specific disassembler option
"insndesc".
include/
* opcode/s390.h (struct s390_opcode): Add field to hold
instruction description.
opcodes/
* s390-mkopc.c: Copy instruction description from s390-opc.txt
into generated operation code table s390-opc.tab.
* s390-opc.c (s390_opformats): Provide NULL as description in
.insn pseudo-mnemonics opcode table.
* s390-dis.c: Add s390-specific disassembler option "insndesc"
and optionally print the instruction description as comment in
the disassembly when it is specified.
gas/
* testsuite/gas/s390/s390.exp: Add new test disassembly test
case "zarch-insndesc".
* testsuite/gas/s390/zarch-insndesc.s: New test case for s390-
specific disassembler option "insndesc".
* testsuite/gas/s390/zarch-insndesc.d: Likewise.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Andreas Krebbel <krebbel@linux.ibm.com>
---
binutils/NEWS | 5 ++
gas/testsuite/gas/s390/s390.exp | 1 +
gas/testsuite/gas/s390/zarch-insndesc.d | 17 +++++++
gas/testsuite/gas/s390/zarch-insndesc.s | 10 ++++
include/opcode/s390.h | 5 +-
opcodes/s390-dis.c | 13 +++++-
opcodes/s390-mkopc.c | 19 +++++---
opcodes/s390-opc.c | 62 ++++++++++++-------------
8 files changed, 92 insertions(+), 40 deletions(-)
create mode 100644 gas/testsuite/gas/s390/zarch-insndesc.d
create mode 100644 gas/testsuite/gas/s390/zarch-insndesc.s
diff --git a/binutils/NEWS b/binutils/NEWS
index 73df7053be4..35b84e62b95 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -19,6 +19,11 @@
* objdump --visualize-jumps is now supported on s390 architecture.
+* The s390 disassembly now optionally includes the instruction description as
+ comment with the s390-specific disassembler option "insndesc":
+ - For objdump it can be enabled with "objdump -M insndesc ...".
+ - In gdb it can be enabled with "set disassembler-options insndesc".
+
Changes in 2.41:
* The MIPS port now supports the Sony Interactive Entertainment Allegrex
diff --git a/gas/testsuite/gas/s390/s390.exp b/gas/testsuite/gas/s390/s390.exp
index 356fba95885..86e2dd492cd 100644
--- a/gas/testsuite/gas/s390/s390.exp
+++ b/gas/testsuite/gas/s390/s390.exp
@@ -37,6 +37,7 @@ if [expr [istarget "s390-*-*"] || [istarget "s390x-*-*"]] then {
run_dump_test "zarch-operands" "{as -m64} {as -march=z9-109}"
run_dump_test "zarch-machine" "{as -m64} {as -march=z900}"
run_dump_test "zarch-optargs" "{as -m64} {as -march=arch12}"
+ run_dump_test "zarch-insndesc" "{as -m64}"
run_list_test "machine-parsing-1" ""
run_list_test "machine-parsing-2" ""
run_list_test "machine-parsing-3" ""
diff --git a/gas/testsuite/gas/s390/zarch-insndesc.d b/gas/testsuite/gas/s390/zarch-insndesc.d
new file mode 100644
index 00000000000..9a121fb2c30
--- /dev/null
+++ b/gas/testsuite/gas/s390/zarch-insndesc.d
@@ -0,0 +1,17 @@
+#name: s390x insndesc
+#objdump: -dr -M insndesc
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+.* <foo>:
+.*: b3 95 00 69 [ ]*cdfbr %f6,%r9 # convert from fixed 32 to long bfp
+ *([\da-f]+): 84 69 00 00 [ ]*brxh %r6,%r9,\1 <foo\+0x\1> # branch relative on index high
+.*: b2 99 5f ff [ ]*srnm 4095\(%r5\) # set rounding mode
+.*: b9 11 00 96 [ ]*lngfr %r9,%r6 # load negative 64<32
+.*: ec 67 92 1c 26 54 [ ]*rnsbgt %r6,%r7,18,28,38 # rotate then and selected bits and test results
+.*: ec 67 0c 8d 0e 5d [ ]*risbhgz %r6,%r7,12,13,14 # rotate then insert selected bits high and zero remaining bits
+.*: b3 96 37 59 [ ]*cxfbra %f5,3,%r9,7 # convert from 32 bit fixed to extended bfp with rounding mode
+.*: ec 67 0c 94 0e 59 [ ]*risbgnz %r6,%r7,12,20,14 # rotate then insert selected bits and zero remaining bits nocc
+.*: 07 07 [ ]*nopr %r7 # no operation
diff --git a/gas/testsuite/gas/s390/zarch-insndesc.s b/gas/testsuite/gas/s390/zarch-insndesc.s
new file mode 100644
index 00000000000..e964315f0af
--- /dev/null
+++ b/gas/testsuite/gas/s390/zarch-insndesc.s
@@ -0,0 +1,10 @@
+.text
+foo:
+ cdfbr %f6,%r9
+ brxh %r6,%r9,.
+ srnm 4095(%r5)
+ lngfr %r9,%r6
+ rnsbgt %r6,%r7,18,28,38
+ risbhgz %r6,%r7,12,13,14
+ cxfbra %f5,3,%r9,7
+ risbgnz %r6,%r7,12,20,14
diff --git a/include/opcode/s390.h b/include/opcode/s390.h
index d540e1dfd00..319bfe2d629 100644
--- a/include/opcode/s390.h
+++ b/include/opcode/s390.h
@@ -81,7 +81,7 @@ enum s390_opcode_cpu_val
struct s390_opcode
{
- /* The opcode name. */
+ /* The opcode name (mnemonic). */
const char * name;
/* The opcode itself. Those bits which will be filled in with
@@ -110,6 +110,9 @@ struct s390_opcode
/* Instruction specific flags. */
unsigned int flags;
+
+ /* Instruction description. */
+ const char * description;
};
/* The table itself is sorted by major opcode number, and is otherwise
diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c
index 8c8a98c4e24..fca965fbb5d 100644
--- a/opcodes/s390-dis.c
+++ b/opcodes/s390-dis.c
@@ -31,6 +31,7 @@
static int opc_index[256];
static int current_arch_mask = 0;
static int option_use_insn_len_bits_p = 0;
+static int option_print_insn_desc = 0;
typedef struct
{
@@ -43,7 +44,8 @@ static const s390_options_t options[] =
{ "esa" , N_("Disassemble in ESA architecture mode") },
{ "zarch", N_("Disassemble in z/Architecture mode") },
{ "insnlength", N_("Print unknown instructions according to "
- "length from first two bits") }
+ "length from first two bits") },
+ { "insndesc", N_("Print instruction description as comment") },
};
/* Set up index table for first opcode byte. */
@@ -63,6 +65,7 @@ disassemble_init_s390 (struct disassemble_info *info)
current_arch_mask = 1 << S390_OPCODE_ZARCH;
option_use_insn_len_bits_p = 0;
+ option_print_insn_desc = 0;
for (p = info->disassembler_options; p != NULL; )
{
@@ -72,6 +75,8 @@ disassemble_init_s390 (struct disassemble_info *info)
current_arch_mask = 1 << S390_OPCODE_ZARCH;
else if (startswith (p, "insnlength"))
option_use_insn_len_bits_p = 1;
+ else if (startswith (p, "insndesc"))
+ option_print_insn_desc = 1;
else
/* xgettext:c-format */
opcodes_error_handler (_("unknown S/390 disassembler option: %s"), p);
@@ -311,6 +316,12 @@ s390_print_insn_with_opcode (bfd_vma memaddr,
else
separator = ',';
}
+
+ /* Optional: instruction name. */
+ if (option_print_insn_desc && opcode->description
+ && opcode->description[0] != '\0')
+ info->fprintf_styled_func (info->stream, dis_style_comment_start, "\t# %s",
+ opcode->description);
}
/* Check whether opcode A's mask is more specific than that of B. */
diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c
index eae0397d497..c6930a3e9b5 100644
--- a/opcodes/s390-mkopc.c
+++ b/opcodes/s390-mkopc.c
@@ -63,6 +63,7 @@ struct op_struct
int mode_bits;
int min_cpu;
int flags;
+ char description[MAX_DESCRIPTION_LEN + 1];
unsigned long long sort_value;
int no_nibbles;
@@ -84,7 +85,7 @@ createTable (void)
static void
insertOpcode (char *opcode, char *mnemonic, char *format,
- int min_cpu, int mode_bits, int flags)
+ int min_cpu, int mode_bits, int flags, char* description)
{
char *str;
unsigned long long sort_value;
@@ -132,6 +133,8 @@ insertOpcode (char *opcode, char *mnemonic, char *format,
op_array[ix].min_cpu = min_cpu;
op_array[ix].mode_bits = mode_bits;
op_array[ix].flags = flags;
+ strncpy (op_array[ix].description, description, MAX_DESCRIPTION_LEN);
+ op_array[ix].description[MAX_DESCRIPTION_LEN] = '\0';
no_ops++;
}
@@ -193,7 +196,7 @@ const struct s390_cond_ext_format s390_crb_extensions[NUM_CRB_EXTENSIONS] =
static void
insertExpandedMnemonic (char *opcode, char *mnemonic, char *format,
- int min_cpu, int mode_bits, int flags)
+ int min_cpu, int mode_bits, int flags, char *description)
{
char *tag;
char prefix[MAX_MNEMONIC_LEN + 1];
@@ -206,7 +209,7 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format,
if (!(tag = strpbrk (mnemonic, "*$")))
{
- insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits, flags);
+ insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits, flags, description);
return;
}
@@ -290,7 +293,7 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format,
return;
}
- insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags);
+ insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags, description);
}
return;
@@ -311,7 +314,8 @@ static const char file_header[] =
" instruction which matches.\n"
" MODE_BITS - zarch or esa\n"
" MIN_CPU - number of the min cpu level required\n"
- " FLAGS - instruction flags. */\n\n"
+ " FLAGS - instruction flags.\n"
+ " DESCRIPTION - description of the instruction. */\n\n"
"const struct s390_opcode s390_opcodes[] =\n {\n";
/* `dumpTable': write opcode table. */
@@ -337,7 +341,8 @@ dumpTable (void)
op_array[ix].format, op_array[ix].format);
printf ("%i, ", op_array[ix].mode_bits);
printf ("%i, ", op_array[ix].min_cpu);
- printf ("%i}", op_array[ix].flags);
+ printf ("%i, ", op_array[ix].flags);
+ printf ("\"%s\" }", op_array[ix].description);
if (ix < no_ops-1)
printf (",\n");
else
@@ -497,7 +502,7 @@ main (void)
str++;
} while (*str != 0);
}
- insertExpandedMnemonic (opcode, mnemonic, format, min_cpu, mode_bits, flag_bits);
+ insertExpandedMnemonic (opcode, mnemonic, format, min_cpu, mode_bits, flag_bits, description);
continue_loop:
;
diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c
index cbfdb3df0b7..e44621a7479 100644
--- a/opcodes/s390-opc.c
+++ b/opcodes/s390-opc.c
@@ -774,37 +774,37 @@ unused_s390_operands_static_asserts (void)
const struct s390_opcode s390_opformats[] =
{
- { "e", OP8(0x00LL), MASK_E, INSTR_E, 3, 0 ,0 },
- { "ri", OP8(0x00LL), MASK_RI_RI, INSTR_RI_RI, 3, 0 ,0 },
- { "rie", OP8(0x00LL), MASK_RIE_RRP, INSTR_RIE_RRP, 3, 0 ,0 },
- { "ril", OP8(0x00LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 0 ,0 },
- { "rilu", OP8(0x00LL), MASK_RIL_RU, INSTR_RIL_RU, 3, 0 ,0 },
- { "ris", OP8(0x00LL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 3, 6 ,0 },
- { "rr", OP8(0x00LL), MASK_RR_RR, INSTR_RR_RR, 3, 0 ,0 },
- { "rre", OP8(0x00LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0 ,0 },
- { "rrf", OP8(0x00LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3, 0 ,0 },
- { "rrs", OP8(0x00LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 3, 6 ,0 },
- { "rs", OP8(0x00LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0 ,0 },
- { "rse", OP8(0x00LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3, 0 ,0 },
- { "rsi", OP8(0x00LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0 ,0 },
- { "rsy", OP8(0x00LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3 ,0 },
- { "rx", OP8(0x00LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0 ,0 },
- { "rxe", OP8(0x00LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 0 ,0 },
- { "rxf", OP8(0x00LL), MASK_RXF_RRRDR, INSTR_RXF_RRRDR, 3, 0 ,0 },
- { "rxy", OP8(0x00LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3 ,0 },
- { "s", OP8(0x00LL), MASK_S_RD, INSTR_S_RD, 3, 0 ,0 },
- { "si", OP8(0x00LL), MASK_SI_URD, INSTR_SI_URD, 3, 0 ,0 },
- { "siy", OP8(0x00LL), MASK_SIY_URD, INSTR_SIY_URD, 3, 3 ,0 },
- { "sil", OP8(0x00LL), MASK_SIL_RDI, INSTR_SIL_RDI, 3, 6 ,0 },
- { "ss", OP8(0x00LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0 ,0 },
- { "sse", OP8(0x00LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0 ,0 },
- { "ssf", OP8(0x00LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 3, 0 ,0 },
- { "vrv", OP8(0x00LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 3, 9 ,0 },
- { "vri", OP8(0x00LL), MASK_VRI_VVUUU, INSTR_VRI_VVUUU, 3, 9 ,0 },
- { "vrx", OP8(0x00LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 3, 9 ,0 },
- { "vrs", OP8(0x00LL), MASK_VRS_RVRDU, INSTR_VRS_RVRDU, 3, 9 ,0 },
- { "vrr", OP8(0x00LL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 3, 9 ,0 },
- { "vsi", OP8(0x00LL), MASK_VSI_URDV, INSTR_VSI_URDV, 3, 10 ,0 },
+ { "e", OP8(0x00LL), MASK_E, INSTR_E, 3, 0, 0, NULL },
+ { "ri", OP8(0x00LL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 0, NULL },
+ { "rie", OP8(0x00LL), MASK_RIE_RRP, INSTR_RIE_RRP, 3, 0, 0, NULL },
+ { "ril", OP8(0x00LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 0, 0, NULL },
+ { "rilu", OP8(0x00LL), MASK_RIL_RU, INSTR_RIL_RU, 3, 0, 0, NULL },
+ { "ris", OP8(0x00LL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 3, 6, 0, NULL },
+ { "rr", OP8(0x00LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, NULL },
+ { "rre", OP8(0x00LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, NULL },
+ { "rrf", OP8(0x00LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3, 0, 0, NULL },
+ { "rrs", OP8(0x00LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 3, 6, 0, NULL },
+ { "rs", OP8(0x00LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, NULL },
+ { "rse", OP8(0x00LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3, 0, 0, NULL },
+ { "rsi", OP8(0x00LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 0, NULL },
+ { "rsy", OP8(0x00LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3, 0, NULL },
+ { "rx", OP8(0x00LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, NULL },
+ { "rxe", OP8(0x00LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 0, 0, NULL },
+ { "rxf", OP8(0x00LL), MASK_RXF_RRRDR, INSTR_RXF_RRRDR, 3, 0, 0, NULL },
+ { "rxy", OP8(0x00LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 0, NULL },
+ { "s", OP8(0x00LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, NULL },
+ { "si", OP8(0x00LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, NULL },
+ { "siy", OP8(0x00LL), MASK_SIY_URD, INSTR_SIY_URD, 3, 3, 0, NULL },
+ { "sil", OP8(0x00LL), MASK_SIL_RDI, INSTR_SIL_RDI, 3, 6, 0, NULL },
+ { "ss", OP8(0x00LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0, 0, NULL },
+ { "sse", OP8(0x00LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 0, NULL },
+ { "ssf", OP8(0x00LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 3, 0, 0, NULL },
+ { "vrv", OP8(0x00LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 3, 9, 0, NULL },
+ { "vri", OP8(0x00LL), MASK_VRI_VVUUU, INSTR_VRI_VVUUU, 3, 9, 0, NULL },
+ { "vrx", OP8(0x00LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 3, 9, 0, NULL },
+ { "vrs", OP8(0x00LL), MASK_VRS_RVRDU, INSTR_VRS_RVRDU, 3, 9, 0, NULL },
+ { "vrr", OP8(0x00LL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 3, 9, 0, NULL },
+ { "vsi", OP8(0x00LL), MASK_VSI_URDV, INSTR_VSI_URDV, 3, 10, 0, NULL },
};
const int s390_num_opformats =
--
2.40.1
next prev parent reply other threads:[~2023-12-15 14:36 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-15 14:36 [PATCH v2 0/7] " Jens Remus
2023-12-15 14:36 ` [PATCH v2 1/7] s390: Fix build when using EXEEXT_FOR_BUILD Jens Remus
2023-12-15 14:36 ` [PATCH v2 2/7] s390: Align letter case of instruction descriptions Jens Remus
2023-12-15 14:36 ` [PATCH v2 3/7] s390: Provide IBM z16 (arch14) " Jens Remus
2023-12-15 14:36 ` [PATCH v2 4/7] s390: Enhance error handling in s390-mkopc Jens Remus
2023-12-15 14:36 ` [PATCH v2 5/7] s390: Use safe string functions and length macros " Jens Remus
2023-12-15 14:36 ` Jens Remus [this message]
2023-12-15 14:36 ` [PATCH v2 7/7] s390: Add suffix to conditional branch instruction descriptions Jens Remus
2023-12-18 12:14 ` [PATCH v2 0/7] s390: Optionally print instruction description in disassembly Nick Clifton
2023-12-20 10:56 ` Andreas Krebbel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231215143616.820185-7-jremus@linux.ibm.com \
--to=jremus@linux.ibm.com \
--cc=binutils@sourceware.org \
--cc=krebbel@linux.ibm.com \
--cc=nickc@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).