This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: options to display mfc command names in spu disassembly comments
- From: luke hutchinson <hutcho dot luke at gmail dot com>
- To: binutils at sourceware dot org
- Date: Sun, 05 Dec 2010 14:56:48 +1100
- Subject: PATCH: options to display mfc command names in spu disassembly comments
- Reply-to: hutcho dot luke at gmail dot com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
This patch adds two machine specific command line options (passed
through via -M), mfc-cmd and mfc-cmd-all. When enabled, disassembled
instructions that have an immediate field are checked if they match mfc
commands. If they do match, then the mfc command name is added to a
comment after the instruction.
Note: patch is applied after previous patch, "PATCH: use symbolic names
when disassembling spu channel insns".
- - Luke
diff -aur binutils-2.20.51.20100908-orig/binutils/doc/binutils.info
binutils-2.20.51.20100908/binutils/doc/binutils.info
- --- binutils-2.20.51.20100908-orig/binutils/doc/binutils.info 2010-12-05
00:02:16.156600863 +0000
+++ binutils-2.20.51.20100908/binutils/doc/binutils.info 2010-12-05
03:43:07.000000000 +0000
@@ -1689,6 +1689,12 @@
`ppcps' selects disassembly for the paired single instructions of
the PPC750CL.
+ For SPU, `mfc-cmd' adds comments to the disassembly for immediate
+ values that match common mfc commands (put and get with optional
+ list and/or fence or barrier modifiers, as well as atomic unit
+ commands). `mfc-cmd-all' adds comments for immediates that match
+ any mfc command.
+
For MIPS, this option controls the printing of instruction mnemonic
names and register names in disassembled instructions. Multiple
selections from the following may be specified as a comma separated
diff -aur binutils-2.20.51.20100908-orig/include/dis-asm.h
binutils-2.20.51.20100908/include/dis-asm.h
- --- binutils-2.20.51.20100908-orig/include/dis-asm.h 2010-12-05
00:02:14.556600862 +0000
+++ binutils-2.20.51.20100908/include/dis-asm.h 2010-12-05
03:05:43.000000000 +0000
@@ -303,6 +303,7 @@
extern void print_i386_disassembler_options (FILE *);
extern void print_mips_disassembler_options (FILE *);
extern void print_ppc_disassembler_options (FILE *);
+extern void print_spu_disassembler_options (FILE *);
extern void print_arm_disassembler_options (FILE *);
extern void parse_arm_disassembler_option (char *);
extern void print_s390_disassembler_options (FILE *);
diff -aur binutils-2.20.51.20100908-orig/opcodes/disassemble.c
binutils-2.20.51.20100908/opcodes/disassemble.c
- --- binutils-2.20.51.20100908-orig/opcodes/disassemble.c 2010-12-05
00:02:14.526600859 +0000
+++ binutils-2.20.51.20100908/opcodes/disassemble.c 2010-12-05
03:06:49.000000000 +0000
@@ -486,6 +486,9 @@
#ifdef ARCH_powerpc
print_ppc_disassembler_options (stream);
#endif
+#ifdef ARCH_spu
+ print_spu_disassembler_options (stream);
+#endif
#ifdef ARCH_i386
print_i386_disassembler_options (stream);
#endif
diff -aur binutils-2.20.51.20100908-orig/opcodes/spu-dis.c
binutils-2.20.51.20100908/opcodes/spu-dis.c
- --- binutils-2.20.51.20100908-orig/opcodes/spu-dis.c 2010-12-05
02:19:17.406600860 +0000
+++ binutils-2.20.51.20100908/opcodes/spu-dis.c 2010-12-05
03:34:17.000000000 +0000
@@ -22,6 +22,7 @@
#include <stdio.h>
#include "sysdep.h"
#include "dis-asm.h"
+#include "opintl.h"
#include "opcode/spu.h"
/* This file provides a disassembler function which uses
@@ -32,6 +33,49 @@
static const struct spu_opcode *spu_disassemble_table[(1<<11)];
+void
+print_spu_disassembler_options (FILE *stream)
+{
+ fprintf (stream, _("\n\
+The following spu specific disassembler options are supported for use\n\
+with the -M switch (multiple options should be separated by commas):\n"));
+
+ fprintf (stream, _(" mfc-cmd Comment immediate values that match
common mfc commands\n"));
+ fprintf (stream, _(" mfc-cmd-all Comment immediate values that match
any mfc command\n"));
+}
+
+struct spu_options
+{
+ unsigned int mfc_cmd_comment_level;
+};
+
+static void
+parse_spu_options (struct spu_options *options, char *string)
+{
+ char *arg;
+
+ options->mfc_cmd_comment_level = 0;
+
+ arg = string;
+ while (arg != NULL)
+ {
+ char *end = strchr (arg, ',');
+ if (end != NULL)
+ *end = 0;
+
+ if (strcmp (arg, "mfc-cmd") == 0)
+ options->mfc_cmd_comment_level = 1;
+ else if (strcmp (arg, "mfc-cmd-all") == 0)
+ options->mfc_cmd_comment_level = 2;
+ else
+ fprintf (stderr, _("warning: ignoring unknown -M%s option\n"),
arg);
+
+ if (end != NULL)
+ *end++ = ',';
+ arg = end;
+ }
+}
+
static void
init_spu_disassemble (void)
{
@@ -130,6 +174,80 @@
return "$ch%u";
}
+/* Convert immediate value to displayable string to be appended to insn
comment. */
+static const char *
+get_comment_for_immediate (int immed, const struct spu_options *options)
+{
+ struct value_string_pair
+ {
+ int val;
+ const char *str;
+ };
+ static const struct value_string_pair mfc_common[] =
+ {
+ {0x0020, " (put)"},
+ {0x0021, " (putb)"},
+ {0x0022, " (putf)"},
+ {0x0024, " (putl)"},
+ {0x0025, " (putlb)"},
+ {0x0026, " (putlf)"},
+ {0x0040, " (get)"},
+ {0x0041, " (getb)"},
+ {0x0042, " (getf)"},
+ {0x0044, " (getl)"},
+ {0x0045, " (getlb)"},
+ {0x0046, " (getlf)"},
+ {0x00b0, " (putlluc)"},
+ {0x00b4, " (putllc)"},
+ {0x00b8, " (putqlluc)"},
+ {0x00d0, " (getllar)"},
+ };
+ static const struct value_string_pair mfc_others[] =
+ {
+ {0x0028, " (puts)"},
+ {0x0029, " (putbs)"},
+ {0x002a, " (putfs)"},
+ {0x0030, " (putr)"},
+ {0x0031, " (putrb)"},
+ {0x0032, " (putrf)"},
+ {0x0034, " (putrl)"},
+ {0x0035, " (putrlb)"},
+ {0x0036, " (putrlf)"},
+ {0x0048, " (gets)"},
+ {0x0049, " (getbs)"},
+ {0x004a, " (getfs)"},
+ {0x0080, " (sdcrt)"},
+ {0x0081, " (sdcrtst)"},
+ {0x0089, " (sdcrz)"},
+ {0x008d, " (sdcrst)"},
+ {0x008f, " (sdcrf)"},
+ {0x00a0, " (sndsig)"},
+ {0x00a1, " (sndsigb)"},
+ {0x00a2, " (sndsigf)"},
+ {0x00c0, " (barrier)"},
+ {0x00c8, " (mfceieio)"},
+ {0x00cc, " (mfcsync)"},
+ };
+ unsigned i;
+ if (options->mfc_cmd_comment_level > 0)
+ {
+ for (i=0; i<sizeof(mfc_common)/sizeof(*mfc_common); ++i)
+ {
+ if (mfc_common[i].val == immed)
+ return mfc_common[i].str;
+ }
+ }
+ if (options->mfc_cmd_comment_level > 1)
+ {
+ for (i=0; i<sizeof(mfc_others)/sizeof(*mfc_others); ++i)
+ {
+ if (mfc_others[i].val == immed)
+ return mfc_others[i].str;
+ }
+ }
+ return "";
+}
+
/* Print a Spu instruction. */
int
@@ -142,6 +260,9 @@
unsigned int insn;
const struct spu_opcode *op_index;
enum spu_insns tag;
+ struct spu_options options;
+
+ parse_spu_options (&options, info->disassembler_options);
status = (*info->read_memory_func) (memaddr, buffer, 4, info);
if (status != 0)
@@ -298,8 +419,18 @@
paren--;
}
}
- - if (hex_value > 16)
- - (*info->fprintf_func) (info->stream, "\t# %x", hex_value);
+ if (hex_value != 0)
+ {
+ const char * comment = get_comment_for_immediate (hex_value,
&options);
+ if (hex_value > 16)
+ {
+ (*info->fprintf_func) (info->stream, "\t# %x%s",
hex_value, comment);
+ }
+ else if (comment[0] != '\0')
+ {
+ (*info->fprintf_func) (info->stream, "\t# %s", comment);
+ }
+ }
}
return 4;
}
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQIcBAEBAgAGBQJM+w1/AAoJEPycJhJ2o4QYY2YP/RkEj2BNdhC/8LO69j1nyqfJ
fXH7lXvQnRBpy1+cTmH/B0ER3K//xnpJtIOaISuQPfMr/K+Eut7+Do5I9HsQkiZq
7QOo57w4f6UbtasF0uPDOxEjD5Gy9Cddsz+0ZrwzcFmTjVjYMSA0xfvKA2aXzXPe
sjEaYTb8PIktoZnwMwcwetpQ0nIiLG5g4CS/n1W/Q79wPf5zTH1wemuz0PoLtDaM
50v0/6Hm2Ugt6x8Kar68xkadNygsZEjEb0k862bcQ+uxD6pQjrkfoqkI49wmvYEh
kP/L8GnIZQHVgZMk1KZ6yemZRM9l+ONJvBqf2cCI2E1fAvjhVW6mWAdwIf7AG/04
9NlIJ1XDHguG0V/bly4gQkfcWAdHmDG+pAhjsJu5sObjNgqJd7H7QQuc6qJk5L9x
2Z0H6hWEtAn2+XBn4ANrP0CmiEhHmzD6nb5tLhePzp4700UHMzbn303nsX0YBNV7
1xeRHnHK46M+pMT81KurkxUK2762VCm6aWgLkdHYkOkzdnAe+vQJTvQ2YqxSJP82
xXsFhLlrPMsVivH2FdYIEbuvDvsER/bWoyx6+S2FLnpOOLeRgJhW0pyg1rk94RIG
PteX/O7wm8uU2XitHnA9Ukkr+E1Pth1G3EsETUyroh7l/GSllHpMCC4Pw8xHo4yn
tlIaFeQJhUNKSpfE46sr
=pcWN
-----END PGP SIGNATURE-----