[PATCH] LoongArch: Add support for the ud macro instruction
Lulu Cai
cailulu@loongson.cn
Mon Dec 1 07:47:26 GMT 2025
In the "ud ui5" macro, the value of ui5 must be in the range 0–31. It
expands to "amswap.w $rd, $r1, $rj", where ui5 specifies the register
number for $rd in the amswap.w instruction, and $rd == $rj.
The test case have been adjusted to no longer report errors for illegal
operands of the amswap.w instruction.
gas/
* config/tc-loongarch.c (check_this_insn_before_appending): No
longer check amswap.w.
* testsuite/gas/loongarch/illegal-operand.l: Update.
* testsuite/gas/loongarch/illegal-operand.s: Update.
* testsuite/gas/loongarch/macro_ud.d: New test.
* testsuite/gas/loongarch/macro_ud.s: New test.
include/
* opcode/loongarch.h: Add new macro for amswap.w.
opcodes/
* loongarch-opc.c: Add macro for ud.
---
gas/config/tc-loongarch.c | 6 ++-
gas/testsuite/gas/loongarch/illegal-operand.l | 10 ++---
gas/testsuite/gas/loongarch/illegal-operand.s | 2 -
gas/testsuite/gas/loongarch/macro_ud.d | 41 +++++++++++++++++++
gas/testsuite/gas/loongarch/macro_ud.s | 32 +++++++++++++++
include/opcode/loongarch.h | 3 ++
opcodes/loongarch-opc.c | 1 +
7 files changed, 85 insertions(+), 10 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/macro_ud.d
create mode 100644 gas/testsuite/gas/loongarch/macro_ud.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index b006c6e6451..df5cf9d903c 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1096,9 +1096,11 @@ check_this_insn_before_appending (struct loongarch_cl_insn *ip)
ip->reloc_info[ip->reloc_num].value = const_0;
ip->reloc_num++;
}
- /* check all atomic memory insns */
+ /* check all atomic memory insns except amswap.w.
+ amswap.w $rd,$r1,$rj ($rd==$rj) is used for ud ui5. */
else if (ip->insn->mask == LARCH_MK_ATOMIC_MEM
- && LARCH_INSN_ATOMIC_MEM (ip->insn_bin))
+ && LARCH_INSN_ATOMIC_MEM (ip->insn_bin)
+ && !LARCH_INSN_AMSWAP_W (ip->insn_bin))
{
/* For AMO insn amswap.[wd], amadd.[wd], etc. */
if (ip->args[0] != 0
diff --git a/gas/testsuite/gas/loongarch/illegal-operand.l b/gas/testsuite/gas/loongarch/illegal-operand.l
index 33e859c742e..09b5ea3aa3e 100644
--- a/gas/testsuite/gas/loongarch/illegal-operand.l
+++ b/gas/testsuite/gas/loongarch/illegal-operand.l
@@ -101,13 +101,11 @@
.*:101: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
.*:102: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
.*:103: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:104: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:105: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:106: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
+.*:107: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
.*:108: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
.*:109: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
-.*:110: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
-.*:111: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
+.*:112: Error: g\?csrxchg require rj != r0 && rj != r1
+.*:113: Error: g\?csrxchg require rj != r0 && rj != r1
.*:114: Error: g\?csrxchg require rj != r0 && rj != r1
.*:115: Error: g\?csrxchg require rj != r0 && rj != r1
-.*:116: Error: g\?csrxchg require rj != r0 && rj != r1
-.*:117: Error: g\?csrxchg require rj != r0 && rj != r1
diff --git a/gas/testsuite/gas/loongarch/illegal-operand.s b/gas/testsuite/gas/loongarch/illegal-operand.s
index 3860539d242..60de2fdc58c 100644
--- a/gas/testsuite/gas/loongarch/illegal-operand.s
+++ b/gas/testsuite/gas/loongarch/illegal-operand.s
@@ -31,8 +31,6 @@ amadd_db.b $r1,$r1,$r2
amadd_db.b $r1,$r2,$r1
amadd_db.h $r1,$r1,$r2
amadd_db.h $r1,$r2,$r1
-amswap.w $r1,$r1,$r2
-amswap.w $r1,$r2,$r1
amswap.d $r1,$r1,$r2
amswap.d $r1,$r2,$r1
amadd.w $r1,$r1,$r2
diff --git a/gas/testsuite/gas/loongarch/macro_ud.d b/gas/testsuite/gas/loongarch/macro_ud.d
new file mode 100644
index 00000000000..dbc1cdcaf00
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/macro_ud.d
@@ -0,0 +1,41 @@
+#as:
+#objdump: -d
+
+.*: file format .*
+
+
+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
diff --git a/gas/testsuite/gas/loongarch/macro_ud.s b/gas/testsuite/gas/loongarch/macro_ud.s
new file mode 100644
index 00000000000..75ebcb8b1b4
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/macro_ud.s
@@ -0,0 +1,32 @@
+ud 0
+ud 1
+ud 2
+ud 3
+ud 4
+ud 5
+ud 6
+ud 7
+ud 8
+ud 9
+ud 10
+ud 11
+ud 12
+ud 13
+ud 14
+ud 15
+ud 16
+ud 17
+ud 18
+ud 19
+ud 20
+ud 21
+ud 22
+ud 23
+ud 24
+ud 25
+ud 26
+ud 27
+ud 28
+ud 29
+ud 30
+ud 31
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index b20c78ddf9f..1696f7d4291 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -73,6 +73,8 @@ extern "C"
#define LARCH_OP_CSRXCHG 0x04000000
#define LARCH_MK_GCSRXCHG 0xff000000
#define LARCH_OP_GCSRXCHG 0x05000000
+ #define LARCH_MK_AMSWAP_W 0xffff8000
+ #define LARCH_OP_AMSWAP_W 0x38600000
#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)
@@ -92,6 +94,7 @@ extern "C"
#define LARCH_INSN_BSTRPICK_D(insn) LARCH_INSN_OPS((insn), BSTRPICK_D)
#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_ATOMIC_MEM(insn) \
((insn & 0xfff80000) == 0x38580000 \
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index fa53021cfae..b443aebb477 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -448,6 +448,7 @@ static struct loongarch_opcode loongarch_macro_opcodes[] =
{ 0, 0, "la.tls.desc", "r,l", INSN_LA_TLS_DESC64_LARGE_ABS, 0 },
{ 0, 0, "la.tls.desc", "r,l", INSN_LA_TLS_DESC64, 0 },
{ 0, 0, "la.tls.desc", "r,r,l", INSN_LA_TLS_DESC64_LARGE_PCREL,0 },
+ { 0, 0, "ud", "u", "amswap.w $r%1,$r1,$r%1", 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list. */
};
--
2.34.1
More information about the Binutils
mailing list