From: Lulu Cai Date: Sat, 13 Dec 2025 07:33:15 +0000 (+0800) Subject: LoongArch: Add disassembly support for ud ui5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8bea934667cdf3046dd388e9d07ca055d4ff5277;p=thirdparty%2Fbinutils-gdb.git LoongArch: Add disassembly support for ud ui5 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. --- 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 index 00000000000..30e580c36ac --- /dev/null +++ b/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud-noaliases.d @@ -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+ : + 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 : + 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 index 00000000000..2997153c3cb --- /dev/null +++ b/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud.d @@ -0,0 +1,18 @@ +#name: Check correct disassembly of ud +#source: dis-amswap-ud.s +#objdump: -d -M numeric + +#... +Disassembly of section \.text: + +0+ : + 0: 38600400 ud 0x0 + 4: 38600421 ud 0x1 + 8: 38600442 ud 0x2 + c: 38600463 ud 0x3 + +0+10 : + 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 index 00000000000..e9937e0c52d --- /dev/null +++ b/binutils/testsuite/binutils-all/loongarch64/dis-amswap-ud.s @@ -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 diff --git a/gas/testsuite/gas/loongarch/macro_ud.d b/gas/testsuite/gas/loongarch/macro_ud.d index dbc1cdcaf00..7ef5b9bfa82 100644 --- a/gas/testsuite/gas/loongarch/macro_ud.d +++ b/gas/testsuite/gas/loongarch/macro_ud.d @@ -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 diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h index fb6f8be68de..3e8a90a2b27 100644 --- a/include/opcode/loongarch.h +++ b/include/opcode/loongarch.h @@ -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; diff --git a/opcodes/loongarch-dis.c b/opcodes/loongarch-dis.c index 2e59bf8035f..05907db2caa 100644 --- a/opcodes/loongarch-dis.c +++ b/opcodes/loongarch-dis.c @@ -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) diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c index 98ce43358c1..6604bd73f00 100644 --- a/opcodes/loongarch-opc.c +++ b/opcodes/loongarch-opc.c @@ -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. */ };