[PATCH v3] LoongArch: Add new annotate option for objdump

zhaozhou <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
Add LoongArch architecture new option, objdump -dM annotate: prints
disassembly along with annotations for dbar instructions.
---
 .../binutils-all/loongarch64/annotate-dbar.d  | 43 +++++++++++
 .../binutils-all/loongarch64/annotate-dbar.s  | 34 +++++++++
 include/opcode/loongarch.h                    |  3 +
 opcodes/loongarch-dis.c                       | 74 +++++++++++++++++++
 4 files changed, 154 insertions(+)
 create mode 100644 binutils/testsuite/binutils-all/loongarch64/annotate-dbar.d
 create mode 100644 binutils/testsuite/binutils-all/loongarch64/annotate-dbar.s

diff --git a/binutils/testsuite/binutils-all/loongarch64/annotate-dbar.d b/binutils/testsuite/binutils-all/loongarch64/annotate-dbar.d
new file mode 100644
index 00000000000..9db6facca7c
--- /dev/null
+++ b/binutils/testsuite/binutils-all/loongarch64/annotate-dbar.d
@@ -0,0 +1,43 @@
+# Skip annotate which reserved hint values such as 0xf, 0x1f and 0x7000.
+#name: Check annotate of dbar
+#source: annotate-dbar.s
+#objdump: -d -M annotate
+
+#...
+Disassembly of section \.text:
+
+0+ <.text>:
+   0:	38720000 	dbar        	0x0	#  RW|RW
+   4:	38720001 	dbar        	0x1	#  RW|R 
+   8:	38720002 	dbar        	0x2	#  RW| W
+   c:	38720003 	dbar        	0x3	#  RW|  
+  10:	38720004 	dbar        	0x4	#  R |RW
+  14:	38720005 	dbar        	0x5	#  R |R 
+  18:	38720006 	dbar        	0x6	#  R | W
+  1c:	38720007 	dbar        	0x7	#  R |  
+  20:	38720008 	dbar        	0x8	#   W|RW
+  24:	38720009 	dbar        	0x9	#   W|R 
+  28:	3872000a 	dbar        	0xa	#   W| W
+  2c:	3872000b 	dbar        	0xb	#   W|  
+  30:	3872000c 	dbar        	0xc	#    |RW
+  34:	3872000d 	dbar        	0xd	#    |R 
+  38:	3872000e 	dbar        	0xe	#    | W
+  3c:	3872000f 	dbar        	0xf
+  40:	38720010 	dbar        	0x10	# CRW|RW
+  44:	38720011 	dbar        	0x11	# CRW|R 
+  48:	38720012 	dbar        	0x12	# CRW| W
+  4c:	38720013 	dbar        	0x13	# CRW|  
+  50:	38720014 	dbar        	0x14	# CR |RW
+  54:	38720015 	dbar        	0x15	# CR |R 
+  58:	38720016 	dbar        	0x16	# CR | W
+  5c:	38720017 	dbar        	0x17	# CR |  
+  60:	38720018 	dbar        	0x18	# C W|RW
+  64:	38720019 	dbar        	0x19	# C W|R 
+  68:	3872001a 	dbar        	0x1a	# C W| W
+  6c:	3872001b 	dbar        	0x1b	# C W|  
+  70:	3872001c 	dbar        	0x1c	# C  |RW
+  74:	3872001d 	dbar        	0x1d	# C  |R 
+  78:	3872001e 	dbar        	0x1e	# C  | W
+  7c:	3872001f 	dbar        	0x1f
+  80:	38720700 	dbar        	0x700	# SA-RAR
+  84:	38727000 	dbar        	0x7000
diff --git a/binutils/testsuite/binutils-all/loongarch64/annotate-dbar.s b/binutils/testsuite/binutils-all/loongarch64/annotate-dbar.s
new file mode 100644
index 00000000000..af5b4f880fa
--- /dev/null
+++ b/binutils/testsuite/binutils-all/loongarch64/annotate-dbar.s
@@ -0,0 +1,34 @@
+dbar  0x0
+dbar  0x1
+dbar  0x2
+dbar  0x3
+dbar  0x4
+dbar  0x5
+dbar  0x6
+dbar  0x7
+dbar  0x8
+dbar  0x9
+dbar  0xa
+dbar  0xb
+dbar  0xc
+dbar  0xd
+dbar  0xe
+dbar  0xf
+dbar  0x10
+dbar  0x11
+dbar  0x12
+dbar  0x13
+dbar  0x14
+dbar  0x15
+dbar  0x16
+dbar  0x17
+dbar  0x18
+dbar  0x19
+dbar  0x1a
+dbar  0x1b
+dbar  0x1c
+dbar  0x1d
+dbar  0x1e
+dbar  0x1f
+dbar  0x700
+dbar  0x7000
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index 294b9424ee5..515b06855fd 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -78,6 +78,8 @@ extern "C"
   #define LARCH_OP_GCSRXCHG 0x05000000
   #define LARCH_MK_AMSWAP_W 0xffff8000
   #define LARCH_OP_AMSWAP_W 0x38600000
+  #define LARCH_MK_DBAR 0xffff8000
+  #define LARCH_OP_DBAR 0x38720000
 
   #define LARCH_INSN_OPS(insn, op) ((insn & LARCH_MK_##op) == LARCH_OP_##op)
   #define LARCH_INSN_ADDI_D(insn) LARCH_INSN_OPS((insn), ADDI_D)
@@ -99,6 +101,7 @@ extern "C"
   #define LARCH_INSN_CSRXCHG(insn) LARCH_INSN_OPS((insn), CSRXCHG)
   #define LARCH_INSN_GCSRXCHG(insn) LARCH_INSN_OPS((insn), GCSRXCHG)
   #define LARCH_INSN_AMSWAP_W(insn) LARCH_INSN_OPS((insn), AMSWAP_W)
+  #define LARCH_INSN_DBAR(insn) LARCH_INSN_OPS((insn), DBAR)
 
   #define LARCH_INSN_ATOMIC_MEM(insn)			\
 	((insn & 0xfff80000) == 0x38580000	\
diff --git a/opcodes/loongarch-dis.c b/opcodes/loongarch-dis.c
index e243963ed49..81fbea39205 100644
--- a/opcodes/loongarch-dis.c
+++ b/opcodes/loongarch-dis.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 
 static bool loongarch_dis_show_aliases = true;
+static bool loongarch_dis_show_annotate = false;
 static const char *const *loongarch_r_disname = NULL;
 static const char *const *loongarch_f_disname = NULL;
 static const char *const *loongarch_fc_disname = NULL;
@@ -117,6 +118,12 @@ parse_loongarch_dis_option (const char *option)
       return 0;
     }
 
+  if (strcmp (option, "annotate") == 0)
+    {
+      loongarch_dis_show_annotate = true;
+      return 0;
+    }
+
   return -1;
 }
 
@@ -242,6 +249,63 @@ dis_one_arg (char esc1, char esc2, const char *bit_field,
   return 0;
 }
 
+static void
+disassemble_annotate_one (insn_t insn, struct disassemble_info *info)
+{
+  if (LARCH_INSN_DBAR (insn))
+    {
+      if ((insn & 0x700) == 0x700)
+	{
+	  info->fprintf_styled_func (info->stream, dis_style_comment_start, "\t# SA-RAR");
+	  return;
+	}
+
+      /* Currently, for reserved hint values such as 0xf, 0x1f and 0x7000, even
+	 though execution behavior matches hint=0 on most hardware, their exact
+	 semantics are undefined.
+	 We adopt a conservative approach and skip annotation for these values.  */
+      if (!(insn & 0x7fe0))
+	{
+	  unsigned int hint = LARCH_GET_RD (insn);
+
+	  /* If hint value is 0xf or 0x1f, its no specific semantics.  */
+	  if ((hint & 0xf) == 0xf)
+	    return;
+
+	  /* dbar imm[4:0] annotate layout:
+	     Bit 0: false denotes W, true denotes null, W declare store after this
+	     dbar are constrained by the barrier.
+	     Bit 1: false denotes R, true denotes null, R declare load after this
+	     dbar are constrained by the barrier.
+	     Bit 3: false denotes W, true denotes null, W declare store before this
+	     dbar are constrained by the barrier.
+	     Bit 4: false denotes R, true denotes null, R declare load before this
+	     dbar are constrained by the barrier.
+	     Bit 4: false denotes null, true denotes C.
+	     Immediate value 0x10 is annotated as CRW|RW that only cached load
+	     and store operations before and after this dbar are constrained
+	     by the barrier.  */
+	  char annotate[7] = {' ', ' ', ' ', '|', ' ', ' ', '\0'};
+	  if ((hint & (1u << 0)) == 0)
+	    annotate[5] = 'W';
+	  if ((hint & (1u << 1)) == 0)
+	    annotate[4] = 'R';
+	  if ((hint & (1u << 2)) == 0)
+	    annotate[2] = 'W';
+	  if ((hint & (1u << 3)) == 0)
+	    annotate[1] = 'R';
+	  if ((hint & (1u << 4)) != 0)
+	    annotate[0] = 'C';
+
+	  info->fprintf_styled_func (info->stream, dis_style_comment_start, "\t# ");
+	  info->fprintf_styled_func (info->stream, dis_style_sub_mnemonic, "%s", annotate);
+	  return;
+	}
+    }
+
+  return;
+}
+
 static void
 disassemble_one (insn_t insn, struct disassemble_info *info)
 {
@@ -319,6 +383,9 @@ disassemble_one (insn_t insn, struct disassemble_info *info)
     free (fake_args);
   }
 
+  if (loongarch_dis_show_annotate)
+    disassemble_annotate_one (insn, info);
+
   if (info->insn_type == dis_branch || info->insn_type == dis_condbranch)
     {
       info->fprintf_styled_func (info->stream, dis_style_comment_start, "\t# ");
@@ -368,5 +435,12 @@ with the -M switch (multiple options should be separated by commas):\n"));
     no-aliases    Use canonical instruction forms.\n"));
   fprintf (stream, _("\n\
     numeric       Print numeric register names, rather than ABI names.\n"));
+  fprintf (stream, _("\n\
+    annotate      Print LoongArch instruction annotations.\n"));
+  fprintf (stream, _("\
+		  dbar annotate layout:\n\
+		  'C': only cached load and store operations are constrained by the barrier;\n\
+		  '|' left‑side 'RW': all load and store before the dbar are constrained by the barrier;\n\
+		  '|' right‑side 'RW': all load and store after the dbar are constrained by the barrier.\n"));
   fprintf (stream, _("\n"));
 }
-- 
2.20.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.