--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+# 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
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
#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;
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;
}
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);
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)
{ 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. */
};