]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
LoongArch: Add disassembly support for ud ui5
authorLulu Cai <cailulu@loongson.cn>
Sat, 13 Dec 2025 07:33:15 +0000 (15:33 +0800)
committercailulu <cailulu@loongson.cn>
Sat, 20 Dec 2025 02:49:47 +0000 (10:49 +0800)
ud ui5, also known as amswap.w rd,$r1,rj(rd==rj), is displayed as
"ud ui5" by default during disassembly. Alternatively, the original
instruction can be printed using the objdump -M no-aliases.

To implement this support, a format specifier "ru0:5,ru5:5" for ud is
applied exclusively during disassembly. This specifier indicates that
registers should be printed using their corresponding numeric values,
and when the instruction is identified as ud, only a single parameter
is displayed.

binutils/

        * testsuite/binutils-all/loongarch64/dis-amswap-ud-noaliases.d:
  New test.
        * testsuite/binutils-all/loongarch64/dis-amswap-ud.d: New test.
        * testsuite/binutils-all/loongarch64/dis-amswap-ud.s: New test.

gas/

        * testsuite/gas/loongarch/macro_ud.d: Update test.

include/

        * opcode/loongarch.h: New macro.

opcodes/

        * loongarch-dis.c (get_loongarch_opcode_by_binfmt): Correct match `ud`.
        (dis_one_arg): Disassemble the `ud` parameter.
        * loongarch-opc.c: Add opcode for "ud" alias.

binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud-noaliases.d [new file with mode: 0644]
binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud.d [new file with mode: 0644]
binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud.s [new file with mode: 0644]
gas/testsuite/gas/loongarch/macro_ud.d
include/opcode/loongarch.h
opcodes/loongarch-dis.c
opcodes/loongarch-opc.c

diff --git a/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud-noaliases.d b/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud-noaliases.d
new file mode 100644 (file)
index 0000000..30e580c
--- /dev/null
@@ -0,0 +1,18 @@
+#name: Check correct disassembly of ud orig instructions
+#source: dis-amswap-ud.s
+#objdump: -d -M numeric,no-aliases
+
+#...
+Disassembly of section \.text:
+
+0+ <ud>:
+   0:  38600400        amswap.w        \$r0, \$r1, \$r0
+   4:  38600421        amswap.w        \$r1, \$r1, \$r1
+   8:  38600442        amswap.w        \$r2, \$r1, \$r2
+   c:  38600463        amswap.w        \$r3, \$r1, \$r3
+
+0+10 <amswap_w>:
+  10:  38600084        amswap.w        \$r4, \$r0, \$r4
+  14:  386008a5        amswap.w        \$r5, \$r2, \$r5
+  18:  386004e6        amswap.w        \$r6, \$r1, \$r7
+  1c:  38600528        amswap.w        \$r8, \$r1, \$r9
diff --git a/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud.d b/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud.d
new file mode 100644 (file)
index 0000000..2997153
--- /dev/null
@@ -0,0 +1,18 @@
+#name: Check correct disassembly of ud
+#source: dis-amswap-ud.s
+#objdump: -d -M numeric
+
+#...
+Disassembly of section \.text:
+
+0+ <ud>:
+   0:  38600400        ud              0x0
+   4:  38600421        ud              0x1
+   8:  38600442        ud              0x2
+   c:  38600463        ud              0x3
+
+0+10 <amswap_w>:
+  10:  38600084        amswap.w        \$r4, \$r0, \$r4
+  14:  386008a5        amswap.w        \$r5, \$r2, \$r5
+  18:  386004e6        amswap.w        \$r6, \$r1, \$r7
+  1c:  38600528        amswap.w        \$r8, \$r1, \$r9
diff --git a/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud.s b/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud.s
new file mode 100644 (file)
index 0000000..e9937e0
--- /dev/null
@@ -0,0 +1,14 @@
+# Disassembly to "ud ui5" or "amswap.w rd, r1, rj" ,rd==rj
+ud:
+ud  0
+ud  1
+amswap.w  $r2,$r1,$r2
+amswap.w  $r3,$r1,$r3
+
+# No disassembly to ud
+amswap_w:
+amswap.w  $r4, $r0, $r4
+amswap.w  $r5, $r2, $r5
+
+amswap.w  $r6, $r1, $r7
+amswap.w  $r8, $r1, $r9
index dbc1cdcaf00d83cc47592a3237ebccec42ffa9ee..7ef5b9bfa8209a38280894e1bf2d1faa4d37cdf3 100644 (file)
@@ -7,35 +7,35 @@
 Disassembly of section \.text:
 
 0+ <\.text>:
- *[0-9a-f]+:   38600400        amswap.w        \$zero, \$ra, \$zero
- *[0-9a-f]+:   38600421        amswap.w        \$ra, \$ra, \$ra
- *[0-9a-f]+:   38600442        amswap.w        \$tp, \$ra, \$tp
- *[0-9a-f]+:   38600463        amswap.w        \$sp, \$ra, \$sp
- *[0-9a-f]+:   38600484        amswap.w        \$a0, \$ra, \$a0
- *[0-9a-f]+:   386004a5        amswap.w        \$a1, \$ra, \$a1
- *[0-9a-f]+:   386004c6        amswap.w        \$a2, \$ra, \$a2
- *[0-9a-f]+:   386004e7        amswap.w        \$a3, \$ra, \$a3
- *[0-9a-f]+:   38600508        amswap.w        \$a4, \$ra, \$a4
- *[0-9a-f]+:   38600529        amswap.w        \$a5, \$ra, \$a5
- *[0-9a-f]+:   3860054a        amswap.w        \$a6, \$ra, \$a6
- *[0-9a-f]+:   3860056b        amswap.w        \$a7, \$ra, \$a7
- *[0-9a-f]+:   3860058c        amswap.w        \$t0, \$ra, \$t0
- *[0-9a-f]+:   386005ad        amswap.w        \$t1, \$ra, \$t1
- *[0-9a-f]+:   386005ce        amswap.w        \$t2, \$ra, \$t2
- *[0-9a-f]+:   386005ef        amswap.w        \$t3, \$ra, \$t3
- *[0-9a-f]+:   38600610        amswap.w        \$t4, \$ra, \$t4
- *[0-9a-f]+:   38600631        amswap.w        \$t5, \$ra, \$t5
- *[0-9a-f]+:   38600652        amswap.w        \$t6, \$ra, \$t6
- *[0-9a-f]+:   38600673        amswap.w        \$t7, \$ra, \$t7
- *[0-9a-f]+:   38600694        amswap.w        \$t8, \$ra, \$t8
- *[0-9a-f]+:   386006b5        amswap.w        \$r21, \$ra, \$r21
- *[0-9a-f]+:   386006d6        amswap.w        \$fp, \$ra, \$fp
- *[0-9a-f]+:   386006f7        amswap.w        \$s0, \$ra, \$s0
- *[0-9a-f]+:   38600718        amswap.w        \$s1, \$ra, \$s1
- *[0-9a-f]+:   38600739        amswap.w        \$s2, \$ra, \$s2
- *[0-9a-f]+:   3860075a        amswap.w        \$s3, \$ra, \$s3
- *[0-9a-f]+:   3860077b        amswap.w        \$s4, \$ra, \$s4
- *[0-9a-f]+:   3860079c        amswap.w        \$s5, \$ra, \$s5
- *[0-9a-f]+:   386007bd        amswap.w        \$s6, \$ra, \$s6
- *[0-9a-f]+:   386007de        amswap.w        \$s7, \$ra, \$s7
- *[0-9a-f]+:   386007ff        amswap.w        \$s8, \$ra, \$s8
+   0:  38600400        ud              0x0
+   4:  38600421        ud              0x1
+   8:  38600442        ud              0x2
+   c:  38600463        ud              0x3
+  10:  38600484        ud              0x4
+  14:  386004a5        ud              0x5
+  18:  386004c6        ud              0x6
+  1c:  386004e7        ud              0x7
+  20:  38600508        ud              0x8
+  24:  38600529        ud              0x9
+  28:  3860054a        ud              0xa
+  2c:  3860056b        ud              0xb
+  30:  3860058c        ud              0xc
+  34:  386005ad        ud              0xd
+  38:  386005ce        ud              0xe
+  3c:  386005ef        ud              0xf
+  40:  38600610        ud              0x10
+  44:  38600631        ud              0x11
+  48:  38600652        ud              0x12
+  4c:  38600673        ud              0x13
+  50:  38600694        ud              0x14
+  54:  386006b5        ud              0x15
+  58:  386006d6        ud              0x16
+  5c:  386006f7        ud              0x17
+  60:  38600718        ud              0x18
+  64:  38600739        ud              0x19
+  68:  3860075a        ud              0x1a
+  6c:  3860077b        ud              0x1b
+  70:  3860079c        ud              0x1c
+  74:  386007bd        ud              0x1d
+  78:  386007de        ud              0x1e
+  7c:  386007ff        ud              0x1f
index fb6f8be68de2a4cbe8d03d87740d3b88abdb8806..3e8a90a2b27acd21645d8b113c9efcf70b02c3eb 100644 (file)
@@ -116,6 +116,7 @@ extern "C"
   #define LARCH_RD_RJ_A0 0x084
   #define LARCH_GET_RD(insn) (insn & 0x1f)
   #define LARCH_GET_RJ(insn) ((insn >> 5) & 0x1f)
+  #define LARCH_GET_RK(insn) ((insn >> 10) & 0x1f)
 
   typedef uint32_t insn_t;
 
index 2e59bf8035f2b1a420f909723dc2debc50f9619b..05907db2caa47ad1fbfb86529e3208eaae6d5092 100644 (file)
@@ -65,7 +65,17 @@ get_loongarch_opcode_by_binfmt (insn_t insn)
        if ((insn & it->mask) == it->match && it->mask
            && !(it->include && !*it->include)
            && !(it->exclude && *it->exclude))
-         return it;
+         {
+           /* ud ui5 need rd==rj. We should continue searching
+              for the next `it` if rd != rj. Furthermore, we need
+              `it->pinfo` to ensure that only the `it` in loongarch
+              alias_opcodes[] is skipped.  */
+           if (LARCH_INSN_AMSWAP_W (insn)
+               && (LARCH_GET_RD (insn) != LARCH_GET_RJ (insn))
+               && (it->pinfo & INSN_DIS_ALIAS))
+             continue;
+           return it;
+         }
     }
   return NULL;
 }
@@ -142,10 +152,19 @@ dis_one_arg (char esc1, char esc2, const char *bit_field,
   insn_t insn = *(insn_t *) info->private_data;
   int32_t imm, u_imm;
   enum disassembler_style style;
+  bool is_ud_2nd_arg = false;
+
+  if (LARCH_INSN_AMSWAP_W (insn)
+      && (LARCH_GET_RD (insn) == LARCH_GET_RJ (insn))
+      && (LARCH_GET_RK (insn) == 1)
+      && loongarch_dis_show_aliases
+      && need_comma)
+    is_ud_2nd_arg = true;
 
   if (esc1)
     {
-      if (need_comma)
+      /* The "ud ui5" does not nedd a comma.  */
+      if (need_comma && !is_ud_2nd_arg)
        info->fprintf_styled_func (info->stream, dis_style_text, ", ");
       need_comma = 1;
       imm = loongarch_decode_imm (bit_field, insn, 1);
@@ -155,7 +174,17 @@ dis_one_arg (char esc1, char esc2, const char *bit_field,
   switch (esc1)
     {
     case 'r':
-      info->fprintf_styled_func (info->stream, dis_style_register, "%s", loongarch_r_disname[u_imm]);
+      switch (esc2)
+       {
+         case 'u':
+           /* The "ud ui5" only needs to print one parameter.  */
+           if (is_ud_2nd_arg)
+             break;
+           info->fprintf_styled_func (info->stream, dis_style_immediate, "0x%x", u_imm);
+           break;
+         default:
+           info->fprintf_styled_func (info->stream, dis_style_register, "%s", loongarch_r_disname[u_imm]);
+       }
       break;
     case 'f':
       switch (esc2)
index 98ce43358c1c339afe50e840efe4df9f6d9dc1ff..6604bd73f001ea94c01853cb92d05ef0d596abcf 100644 (file)
@@ -507,6 +507,7 @@ static struct loongarch_opcode loongarch_alias_opcodes[] =
   { 0x60000000,        0xfc0003e0,     "bgtz",         "r0:5,sb10:16<<2",              0,      0, 0, INSN_DIS_ALIAS }, /* blt zero, rd, offset */
   { 0x64000000,        0xfc00001f,     "bgez",         "r5:5,sb10:16<<2",              0,      0, 0, INSN_DIS_ALIAS }, /* bge rj, zero, offset */
   { 0x64000000,        0xfc0003e0,     "blez",         "r0:5,sb10:16<<2",              0,      0, 0, INSN_DIS_ALIAS }, /* bge zero, rd, offset */
+  { 0x38600400,        0xfffffc00,     "ud",           "ru0:5,ru5:5",                  0,      0, 0, INSN_DIS_ALIAS }, /* amswap.w rd, $r1, rj, rj==rd */
   { 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list.  */
 };