summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuzhensong <liuzhensong@loongson.cn>2021-10-22 16:42:06 +0800
committerAlan Modra <amodra@gmail.com>2021-10-24 21:36:32 +1030
commit4462d7c440247bfcdc464412332bbec13b8aab12 (patch)
tree7559eea153d11930124e45d3fa6ead17ceefde8e
parente9a0721f8274daeffaedbc3cabc12c52d43a38a7 (diff)
downloadbinutils-gdb-4462d7c440247bfcdc464412332bbec13b8aab12.tar.gz
LoongArch gas support
2021-10-22 Chenghua Xu <xuchenghua@loongson.cn> Zhensong Liu <liuzhensong@loongson.cn> Weinan Liu <liuweinan@loongson.cn> Xiaolin Tang <tangxiaolin@loongson.cn> gas/ * Makefile.am: Add LoongArch. * NEWS: Mention LoongArch support. * config/loongarch-lex-wrapper.c: New. * config/loongarch-lex.h: New. * config/loongarch-lex.l: New. * config/loongarch-parse.y: New. * config/tc-loongarch.c: New. * config/tc-loongarch.h: New. * configure.ac: Add LoongArch. * configure.tgt: Likewise. * doc/as.texi: Likewise. * doc/c-loongarch.texi: Likewise. * Makefile.in: Regenerate. * configure: Regenerate. * po/POTFILES.in: Regenerate. gas/testsuite/ * gas/all/gas.exp: Add LoongArch. * gas/elf/elf.exp: Likewise. * gas/loongarch/4opt_op.d: New. * gas/loongarch/4opt_op.s: Likewise. * gas/loongarch/fix_op.d: Likewise. * gas/loongarch/fix_op.s: Likewise. * gas/loongarch/float_op.d: Likewise. * gas/loongarch/float_op.s: Likewise. * gas/loongarch/imm_op.d: Likewise. * gas/loongarch/imm_op.s: Likewise. * gas/loongarch/jmp_op.d: Likewise. * gas/loongarch/jmp_op.s: Likewise. * gas/loongarch/load_store_op.d: Likewise. * gas/loongarch/load_store_op.s: Likewise. * gas/loongarch/loongarch.exp: Likewise. * gas/loongarch/macro_op.d: Likewise. * gas/loongarch/macro_op.s: Likewise. * gas/loongarch/nop.d: Likewise. * gas/loongarch/nop.s: Likewise. * gas/loongarch/privilege_op.d: Likewise. * gas/loongarch/privilege_op.s: Likewise. * gas/loongarch/syscall.d: Likewise. * gas/loongarch/syscall.s: Likewise. * lib/gas-defs.exp: Add LoongArch.
-rw-r--r--gas/Makefile.am17
-rw-r--r--gas/Makefile.in28
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/loongarch-lex-wrapper.c20
-rw-r--r--gas/config/loongarch-lex.h34
-rw-r--r--gas/config/loongarch-lex.l61
-rw-r--r--gas/config/loongarch-parse.y441
-rw-r--r--gas/config/tc-loongarch.c1382
-rw-r--r--gas/config/tc-loongarch.h91
-rwxr-xr-xgas/configure17
-rw-r--r--gas/configure.ac13
-rw-r--r--gas/configure.tgt6
-rw-r--r--gas/doc/as.texi31
-rw-r--r--gas/doc/c-loongarch.texi39
-rw-r--r--gas/po/POTFILES.in1
-rw-r--r--gas/testsuite/gas/all/gas.exp5
-rw-r--r--gas/testsuite/gas/elf/elf.exp1
-rw-r--r--gas/testsuite/gas/loongarch/4opt_op.d70
-rw-r--r--gas/testsuite/gas/loongarch/4opt_op.s61
-rw-r--r--gas/testsuite/gas/loongarch/fix_op.d134
-rw-r--r--gas/testsuite/gas/loongarch/fix_op.s125
-rw-r--r--gas/testsuite/gas/loongarch/float_op.d85
-rw-r--r--gas/testsuite/gas/loongarch/float_op.s76
-rw-r--r--gas/testsuite/gas/loongarch/imm_op.d48
-rw-r--r--gas/testsuite/gas/loongarch/imm_op.s39
-rw-r--r--gas/testsuite/gas/loongarch/jmp_op.d68
-rw-r--r--gas/testsuite/gas/loongarch/jmp_op.s22
-rw-r--r--gas/testsuite/gas/loongarch/load_store_op.d178
-rw-r--r--gas/testsuite/gas/loongarch/load_store_op.s169
-rw-r--r--gas/testsuite/gas/loongarch/loongarch.exp23
-rw-r--r--gas/testsuite/gas/loongarch/macro_op.d733
-rw-r--r--gas/testsuite/gas/loongarch/macro_op.s29
-rw-r--r--gas/testsuite/gas/loongarch/nop.d10
-rw-r--r--gas/testsuite/gas/loongarch/nop.s2
-rw-r--r--gas/testsuite/gas/loongarch/privilege_op.d44
-rw-r--r--gas/testsuite/gas/loongarch/privilege_op.s35
-rw-r--r--gas/testsuite/gas/loongarch/syscall.d11
-rw-r--r--gas/testsuite/gas/loongarch/syscall.s2
-rw-r--r--gas/testsuite/lib/gas-defs.exp4
39 files changed, 4152 insertions, 5 deletions
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 34190e78b8c..7678ee61144 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -154,6 +154,7 @@ TARGET_CPU_CFILES = \
config/tc-ip2k.c \
config/tc-iq2000.c \
config/tc-lm32.c \
+ config/tc-loongarch.c \
config/tc-m32c.c \
config/tc-m32r.c \
config/tc-m68hc11.c \
@@ -374,7 +375,8 @@ EXTRA_SCRIPTS = .gdbinit
EXTRA_DIST = config/m68k-parse.c itbl-parse.c itbl-parse.h itbl-lex.c \
config/bfin-parse.c config/bfin-parse.h config/bfin-lex.c \
config/rl78-parse.c config/rl78-parse.h \
- config/rx-parse.c config/rx-parse.h
+ config/rx-parse.c config/rx-parse.h \
+ config/loongarch-parse.c config/loongarch-parse.h config/loongarch-lex.c
diststuff: $(EXTRA_DIST) info
@@ -471,6 +473,19 @@ config/rx-parse.c: $(srcdir)/config/rx-parse.y
config/rx-parse.h: config/rx-parse.c
@true
+# The LoongArch lexical analyzer and parser.
+EXTRA_as_new_SOURCES += config/loongarch-parse.y
+config/loongarch-parse.c: $(srcdir)/config/loongarch-parse.y
+ $(SHELL) $(YLWRAP) $(srcdir)/config/loongarch-parse.y y.tab.c $@ y.tab.h config/loongarch-parse.h -- $(YACCCOMPILE) -d ;
+config/loongarch-parse.h: config/loongarch-parse.c
+ @true
+
+EXTRA_as_new_SOURCES += config/loongarch-lex.l
+config/loongarch-lex.c: $(srcdir)/config/loongarch-lex.l
+ $(SHELL) $(YLWRAP) $(srcdir)/config/loongarch-lex.l lex.yy.c $@ -- $(LEXCOMPILE)
+
+config/loongarch-lex-wrapper.@OBJEXT@: config/loongarch-lex.c config/loongarch-parse.h
+
# The mips instruction table specification lexical analyzer and parser.
itbl-lex-wrapper.@OBJEXT@: itbl-lex.c itbl-parse.h
diff --git a/gas/Makefile.in b/gas/Makefile.in
index f3d66b8e8b6..ff11adb0f70 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -544,6 +544,7 @@ TARGET_CPU_CFILES = \
config/tc-ip2k.c \
config/tc-iq2000.c \
config/tc-lm32.c \
+ config/tc-loongarch.c \
config/tc-m32c.c \
config/tc-m32r.c \
config/tc-m68hc11.c \
@@ -757,7 +758,8 @@ EXTRA_SCRIPTS = .gdbinit
EXTRA_DIST = config/m68k-parse.c itbl-parse.c itbl-parse.h itbl-lex.c \
config/bfin-parse.c config/bfin-parse.h config/bfin-lex.c \
config/rl78-parse.c config/rl78-parse.h \
- config/rx-parse.c config/rx-parse.h
+ config/rx-parse.c config/rx-parse.h \
+ config/loongarch-parse.c config/loongarch-parse.h config/loongarch-lex.c
DISTCLEANFILES = targ-cpu.h obj-format.h targ-env.h itbl-cpu.h cgen-desc.h
@@ -789,12 +791,15 @@ as_new_LDADD = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
$(extra_objects) $(GASLIBS) $(LIBINTL_DEP)
+
+# The LoongArch lexical analyzer and parser.
EXTRA_as_new_SOURCES = $(CFILES) $(HFILES) $(TARGET_CPU_CFILES) \
$(TARGET_CPU_HFILES) $(TARGET_EXTRA_FILES) $(TARG_ENV_CFILES) \
$(OBJ_FORMAT_CFILES) $(OBJ_FORMAT_HFILES) \
$(CONFIG_ATOF_CFILES) $(MULTI_CFILES) config/m68k-parse.y \
config/bfin-parse.y config/bfin-lex.l config/rl78-parse.y \
- config/rx-parse.y
+ config/rx-parse.y config/loongarch-parse.y \
+ config/loongarch-lex.l
EXPECT = expect
RUNTEST = runtest
RUNTESTFLAGS =
@@ -939,6 +944,8 @@ config/tc-iq2000.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
config/tc-lm32.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
+config/tc-loongarch.$(OBJEXT): config/$(am__dirstamp) \
+ config/$(DEPDIR)/$(am__dirstamp)
config/tc-m32c.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
config/tc-m32r.$(OBJEXT): config/$(am__dirstamp) \
@@ -1085,6 +1092,10 @@ config/rl78-parse.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
config/rx-parse.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
+config/loongarch-parse.$(OBJEXT): config/$(am__dirstamp) \
+ config/$(DEPDIR)/$(am__dirstamp)
+config/loongarch-lex.$(OBJEXT): config/$(am__dirstamp) \
+ config/$(DEPDIR)/$(am__dirstamp)
as-new$(EXEEXT): $(as_new_OBJECTS) $(as_new_DEPENDENCIES) $(EXTRA_as_new_DEPENDENCIES)
@rm -f as-new$(EXEEXT)
@@ -1146,6 +1157,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/e-i386coff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/e-i386elf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/e-mipself.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/loongarch-lex.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/loongarch-parse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/m68k-parse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-aout.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-coff.Po@am__quote@
@@ -1183,6 +1196,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-ip2k.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-iq2000.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-lm32.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-loongarch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-m32c.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-m32r.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-m68hc11.Po@am__quote@
@@ -1452,6 +1466,8 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
-rm -f config/bfin-lex.c
-rm -f config/bfin-parse.c
+ -rm -f config/loongarch-lex.c
+ -rm -f config/loongarch-parse.c
-rm -f config/m68k-parse.c
-rm -f config/rl78-parse.c
-rm -f config/rx-parse.c
@@ -1601,6 +1617,14 @@ config/rx-parse.c: $(srcdir)/config/rx-parse.y
$(SHELL) $(YLWRAP) $(srcdir)/config/rx-parse.y y.tab.c $@ y.tab.h config/rx-parse.h -- $(YACCCOMPILE) -d ;
config/rx-parse.h: config/rx-parse.c
@true
+config/loongarch-parse.c: $(srcdir)/config/loongarch-parse.y
+ $(SHELL) $(YLWRAP) $(srcdir)/config/loongarch-parse.y y.tab.c $@ y.tab.h config/loongarch-parse.h -- $(YACCCOMPILE) -d ;
+config/loongarch-parse.h: config/loongarch-parse.c
+ @true
+config/loongarch-lex.c: $(srcdir)/config/loongarch-lex.l
+ $(SHELL) $(YLWRAP) $(srcdir)/config/loongarch-lex.l lex.yy.c $@ -- $(LEXCOMPILE)
+
+config/loongarch-lex-wrapper.@OBJEXT@: config/loongarch-lex.c config/loongarch-parse.h
# The mips instruction table specification lexical analyzer and parser.
diff --git a/gas/NEWS b/gas/NEWS
index de4c61b320d..09fade54087 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for the LoongArch instruction set.
+
* Add a command-line option, -muse-unaligned-vector-move, for x86 target
to encode aligned vector move as unaligned vector move.
diff --git a/gas/config/loongarch-lex-wrapper.c b/gas/config/loongarch-lex-wrapper.c
new file mode 100644
index 00000000000..b3d290dc9fe
--- /dev/null
+++ b/gas/config/loongarch-lex-wrapper.c
@@ -0,0 +1,20 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+#include "sysdep.h"
+#include "config/loongarch-lex.c"
diff --git a/gas/config/loongarch-lex.h b/gas/config/loongarch-lex.h
new file mode 100644
index 00000000000..e2b3a4e5560
--- /dev/null
+++ b/gas/config/loongarch-lex.h
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+
+struct yy_buffer_state;
+
+
+struct yy_buffer_state *yy_scan_string (const char *);
+void yy_delete_buffer (struct yy_buffer_state *b);
+void get_internal_label (expressionS *label_expr,
+ unsigned long label,
+ int augend);
+int
+loongarch_parse_expr (const char *expr,
+ struct reloc_info *reloc_stack_top,
+ size_t max_reloc_num,
+ size_t *reloc_num,
+ offsetT *imm);
diff --git a/gas/config/loongarch-lex.l b/gas/config/loongarch-lex.l
new file mode 100644
index 00000000000..8ced60a43ae
--- /dev/null
+++ b/gas/config/loongarch-lex.l
@@ -0,0 +1,61 @@
+%option noyywrap
+/*
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+%{
+#include "as.h"
+#include "loongarch-parse.h"
+
+/* Flex generates static functions "input" & "unput" which are not used. */
+#define YY_NO_INPUT
+#define YY_NO_UNPUT
+%}
+
+D [0-9]
+/* We consider anything greater than \x7f to be a "letter" for UTF-8
+ support. See the lex_type array in ../read.c. */
+L [a-zA-Z_\.\$\x80-\xff]
+H [0-9A-Fa-f]
+
+hex 0[xX]{H}+
+oct 0[0-7]+
+bin 0[bB][01]+
+dec ([1-9]{D}*)|0
+id ({D}+[fb])|({L}({D}|{L})*)|(:{dec}[bf])
+ws [ \t\v\f]+
+
+%%
+
+{dec} { yylval.imm = strtoull (yytext, 0, 0); return INTEGER; }
+{hex} { yylval.imm = strtoull (yytext + 2, 0, 16); return INTEGER; }
+{bin} { yylval.imm = strtoull (yytext + 2, 0, 2); return INTEGER; }
+{oct} { yylval.imm = strtoull (yytext + 1, 0, 8); return INTEGER; }
+{id} { yylval.c_str = strdup (yytext);return IDENTIFIER; }
+{ws} { }
+
+">>" { return RIGHT_OP; }
+"<<" { return LEFT_OP; }
+"&&" { return AND_OP; }
+"||" { return OR_OP; }
+"<=" { return LE_OP; }
+">=" { return GE_OP; }
+"==" { return EQ_OP; }
+"!=" { return NE_OP; }
+. { return yytext[0];}
+
+%%
diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y
new file mode 100644
index 00000000000..a7477fbb66a
--- /dev/null
+++ b/gas/config/loongarch-parse.y
@@ -0,0 +1,441 @@
+/*
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+%{
+#include "as.h"
+#include "loongarch-lex.h"
+#include "loongarch-parse.h"
+static void yyerror (const char *s ATTRIBUTE_UNUSED)
+{
+};
+int yylex (void);
+
+
+static struct reloc_info *top, *end;
+
+static expressionS const_0 =
+{
+ .X_op = O_constant,
+ .X_add_number = 0
+};
+
+static int
+is_const (struct reloc_info *info)
+{
+ return (info->type == BFD_RELOC_LARCH_SOP_PUSH_ABSOLUTE
+ && info->value.X_op == O_constant);
+}
+
+int
+loongarch_parse_expr (const char *expr,
+ struct reloc_info *reloc_stack_top,
+ size_t max_reloc_num,
+ size_t *reloc_num,
+ offsetT *imm)
+{
+ int ret;
+ struct yy_buffer_state *buffstate;
+ top = reloc_stack_top;
+ end = top + max_reloc_num;
+ buffstate = yy_scan_string (expr);
+ ret = yyparse ();
+
+ if (ret == 0)
+ {
+ if (is_const (top - 1))
+ *imm = (--top)->value.X_add_number;
+ else
+ *imm = 0;
+ *reloc_num = top - reloc_stack_top;
+ }
+ yy_delete_buffer (buffstate);
+
+ return ret;
+}
+
+static void
+emit_const (offsetT imm)
+{
+ if (end <= top)
+ as_fatal (_("expr too huge"));
+ top->type = BFD_RELOC_LARCH_SOP_PUSH_ABSOLUTE;
+ top->value.X_op = O_constant;
+ top->value.X_add_number = imm;
+ top++;
+}
+
+static const char *
+my_getExpression (expressionS *ep, const char *str)
+{
+ char *save_in, *ret;
+ if (*str == ':')
+ {
+ unsigned long j;
+ char *str_1 = (char *) str;
+ str_1++;
+ j = strtol (str_1, &str_1, 10);
+ get_internal_label (ep, j, *str_1 == 'f');
+ return NULL;
+ }
+ save_in = input_line_pointer;
+ input_line_pointer = (char *)str;
+ expression (ep);
+ ret = input_line_pointer;
+ input_line_pointer = save_in;
+ return ret;
+}
+
+static void
+reloc (const char *op_c_str, const char *id_c_str, offsetT addend)
+{
+ expressionS id_sym_expr;
+
+ if (end <= top)
+ as_fatal (_("expr too huge"));
+
+ if (id_c_str)
+ {
+ my_getExpression (&id_sym_expr, id_c_str);
+ id_sym_expr.X_add_number += addend;
+ }
+ else
+ {
+ id_sym_expr.X_op = O_constant;
+ id_sym_expr.X_add_number = addend;
+ }
+
+ if (strcmp (op_c_str, "abs") == 0)
+ {
+ top->value = id_sym_expr;
+ top->type = BFD_RELOC_LARCH_SOP_PUSH_ABSOLUTE;
+ top++;
+ }
+ else if (strcmp (op_c_str, "pcrel") == 0)
+ {
+ top->value = id_sym_expr;
+ top->type = BFD_RELOC_LARCH_SOP_PUSH_PCREL;
+ top++;
+ }
+ else if (strcmp (op_c_str, "gprel") == 0)
+ {
+ top->value = id_sym_expr;
+ top->type = BFD_RELOC_LARCH_SOP_PUSH_GPREL;
+ top++;
+ }
+ else if (strcmp (op_c_str, "tprel") == 0)
+ {
+ top->value = id_sym_expr;
+ top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL;
+ top++;
+ }
+ else if (strcmp (op_c_str, "tlsgot") == 0)
+ {
+ top->value = id_sym_expr;
+ top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT;
+ top++;
+ }
+ else if (strcmp (op_c_str, "tlsgd") == 0)
+ {
+ top->value = id_sym_expr;
+ top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_GD;
+ top++;
+ }
+ else if (strcmp (op_c_str, "plt") == 0)
+ {
+ top->value = id_sym_expr;
+ top->type = BFD_RELOC_LARCH_SOP_PUSH_PLT_PCREL;
+ top++;
+ }
+ else
+ as_fatal (_("unknown reloc hint: %s"), op_c_str);
+}
+
+static void
+emit_unary (char op)
+{
+ struct reloc_info *s_top = top - 1;
+ if (is_const (s_top))
+ {
+ offsetT opr = s_top->value.X_add_number;
+ switch (op)
+ {
+ case '+':
+ break;
+ case '-':
+ opr = -opr;
+ break;
+ case '~':
+ opr = ~opr;
+ break;
+ case '!':
+ opr = !opr;
+ break;
+ default:
+ abort ();
+ }
+ s_top->value.X_add_number = opr;
+ }
+ else
+ {
+ if (end <= top)
+ as_fatal (_("expr too huge"));
+ switch (op)
+ {
+ case '!':
+ top->type = BFD_RELOC_LARCH_SOP_NOT;
+ break;
+ default:
+ abort ();
+ }
+ top->value = const_0;
+ top++;
+ }
+}
+
+static void
+emit_bin (int op)
+{
+ struct reloc_info *last_1st = top - 1, *last_2nd = top - 2;
+ if (is_const (last_1st) && is_const (last_2nd))
+ {
+ offsetT opr1 = last_2nd->value.X_add_number;
+ offsetT opr2 = last_1st->value.X_add_number;
+ switch (op)
+ {
+ case '*':
+ opr1 = opr1 * opr2;
+ break;
+ case '/':
+ opr1 = opr1 / opr2;
+ break;
+ case '%':
+ opr1 = opr1 % opr2;
+ break;
+ case '+':
+ opr1 = opr1 + opr2;
+ break;
+ case '-':
+ opr1 = opr1 - opr2;
+ break;
+ case LEFT_OP:
+ opr1 = opr1 << opr2;
+ break;
+ case RIGHT_OP:
+ /* Algorithm right shift. */
+ opr1 = (offsetT)opr1 >> (offsetT)opr2;
+ break;
+ case '<':
+ opr1 = opr1 < opr2;
+ break;
+ case '>':
+ opr1 = opr1 > opr2;
+ break;
+ case LE_OP:
+ opr1 = opr1 <= opr2;
+ break;
+ case GE_OP:
+ opr1 = opr1 >= opr2;
+ break;
+ case EQ_OP:
+ opr1 = opr1 == opr2;
+ break;
+ case NE_OP:
+ opr1 = opr1 != opr2;
+ break;
+ case '&':
+ opr1 = opr1 & opr2;
+ break;
+ case '^':
+ opr1 = opr1 ^ opr2;
+ break;
+ case '|':
+ opr1 = opr1 | opr2;
+ break;
+ case AND_OP:
+ opr1 = opr1 && opr2;
+ break;
+ case OR_OP:
+ opr1 = opr1 || opr2;
+ break;
+ default:
+ abort ();
+ }
+ last_2nd->value.X_add_number = opr1;
+ last_1st->type = 0;
+ top--;
+ }
+ else
+ {
+ if (end <= top)
+ as_fatal (_("expr too huge"));
+ switch (op)
+ {
+ case '+':
+ top->type = BFD_RELOC_LARCH_SOP_ADD;
+ break;
+ case '-':
+ top->type = BFD_RELOC_LARCH_SOP_SUB;
+ break;
+ case LEFT_OP:
+ top->type = BFD_RELOC_LARCH_SOP_SL;
+ break;
+ case RIGHT_OP:
+ top->type = BFD_RELOC_LARCH_SOP_SR;
+ break;
+ case '&':
+ top->type = BFD_RELOC_LARCH_SOP_AND;
+ break;
+ default:
+ abort ();
+ }
+ top->value = const_0;
+ top++;
+ }
+}
+
+static void
+emit_if_else (void)
+{
+ struct reloc_info *last_1st = top - 1;
+ struct reloc_info *last_2nd = top - 2;
+ struct reloc_info *last_3rd = top - 3;
+ if (is_const (last_1st) && is_const (last_2nd) && is_const (last_3rd))
+ {
+ offsetT opr1 = last_3rd->value.X_add_number;
+ offsetT opr2 = last_2nd->value.X_add_number;
+ offsetT opr3 = last_1st->value.X_add_number;
+ opr1 = opr1 ? opr2 : opr3;
+ last_3rd->value.X_add_number = opr1;
+ last_2nd->type = 0;
+ last_1st->type = 0;
+ top -= 2;
+ }
+ else
+ {
+ if (end <= top)
+ as_fatal (_("expr too huge"));
+ top->type = BFD_RELOC_LARCH_SOP_IF_ELSE;
+ top->value = const_0;
+ top++;
+ }
+}
+
+%}
+
+%union {
+char *c_str;
+offsetT imm;
+}
+
+%token <imm> INTEGER
+%token <c_str> IDENTIFIER
+%type <imm> addend
+
+%token LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP AND_OP OR_OP
+%start expression
+%%
+
+primary_expression
+ : INTEGER {emit_const ($1);}
+ | '(' expression ')'
+ | '%' IDENTIFIER '(' IDENTIFIER addend ')' {reloc ($2, $4, $5); free ($2); free ($4);}
+ | '%' IDENTIFIER '(' INTEGER addend ')' {reloc ($2, NULL, $4 + $5); free ($2);}
+ ;
+
+addend
+ : addend '-' INTEGER {$$ -= $3;}
+ | addend '+' INTEGER {$$ += $3;}
+ | {$$ = 0;}
+ ;
+
+unary_expression
+ : primary_expression
+ | '+' unary_expression {emit_unary ('+');}
+ | '-' unary_expression {emit_unary ('-');}
+ | '~' unary_expression {emit_unary ('~');}
+ | '!' unary_expression {emit_unary ('!');}
+ ;
+
+multiplicative_expression
+ : unary_expression
+ | multiplicative_expression '*' unary_expression {emit_bin ('*');}
+ | multiplicative_expression '/' unary_expression {emit_bin ('/');}
+ | multiplicative_expression '%' unary_expression {emit_bin ('%');}
+ ;
+
+additive_expression
+ : multiplicative_expression
+ | additive_expression '+' multiplicative_expression {emit_bin ('+');}
+ | additive_expression '-' multiplicative_expression {emit_bin ('-');}
+ ;
+
+shift_expression
+ : additive_expression
+ | shift_expression LEFT_OP additive_expression {emit_bin (LEFT_OP);}
+ | shift_expression RIGHT_OP additive_expression {emit_bin (RIGHT_OP);}
+ ;
+
+relational_expression
+ : shift_expression
+ | relational_expression '<' shift_expression {emit_bin ('<');}
+ | relational_expression '>' shift_expression {emit_bin ('>');}
+ | relational_expression LE_OP shift_expression {emit_bin (LE_OP);}
+ | relational_expression GE_OP shift_expression {emit_bin (GE_OP);}
+ ;
+
+equality_expression
+ : relational_expression
+ | equality_expression EQ_OP relational_expression {emit_bin (EQ_OP);}
+ | equality_expression NE_OP relational_expression {emit_bin (NE_OP);}
+ ;
+
+and_expression
+ : equality_expression
+ | and_expression '&' equality_expression {emit_bin ('&');}
+ ;
+
+exclusive_or_expression
+ : and_expression
+ | exclusive_or_expression '^' and_expression {emit_bin ('^');}
+ ;
+
+inclusive_or_expression
+ : exclusive_or_expression
+ | inclusive_or_expression '|' exclusive_or_expression {emit_bin ('|');}
+ ;
+
+logical_and_expression
+ : inclusive_or_expression
+ | logical_and_expression AND_OP inclusive_or_expression {emit_bin (AND_OP);}
+ ;
+
+logical_or_expression
+ : logical_and_expression
+ | logical_or_expression OR_OP logical_and_expression {emit_bin (OR_OP);}
+ ;
+
+conditional_expression
+ : logical_or_expression
+ | logical_or_expression '?' expression ':' conditional_expression {emit_if_else ();}
+ ;
+
+expression
+ : conditional_expression
+ ;
+%%
+
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
new file mode 100644
index 00000000000..f7235a18864
--- /dev/null
+++ b/gas/config/tc-loongarch.c
@@ -0,0 +1,1382 @@
+/* tc-loongarch.c -- Assemble for the LoongArch ISA
+
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ Contributed by Loongson Ltd.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the license, or
+ (at your option) any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+#include "as.h"
+#include "dw2gencfi.h"
+#include "loongarch-lex.h"
+#include "elf/loongarch.h"
+#include "opcode/loongarch.h"
+#include "obj-elf.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+/* All information about an instruction during assemble. */
+struct loongarch_cl_insn
+{
+ /* First split string. */
+ const char *name;
+ const char *arg_strs[MAX_ARG_NUM_PLUS_2];
+ size_t arg_num;
+
+ /* Second analyze name_str and each actual args string to match the insn
+ in 'loongarch-opc.c'. And actual args may need be relocated.
+ We get length of insn. If 'insn_length == 0 && insn_mo->macro != NULL',
+ it's a macro insntruction and we call 'md_assemble' recursively
+ after expanding it. */
+ int match_now;
+ int all_match;
+
+ const struct loongarch_opcode *insn;
+ size_t insn_length;
+
+ offsetT args[MAX_ARG_NUM_PLUS_2];
+ struct reloc_info reloc_info[MAX_RELOC_NUMBER_A_INSN];
+ size_t reloc_num;
+
+ /* For relax reserved. We not support relax now.
+ 'insn_length < relax_max_length' means need to relax.
+ And 'insn_length == relax_max_length' means no need to relax. */
+ size_t relax_max_length;
+ relax_substateT subtype;
+
+ /* Then we get the binary representation of insn
+ and write it in to section. */
+ insn_t insn_bin;
+
+ /* The frag that contains the instruction. */
+ struct frag *frag;
+ /* The offset into FRAG of the first instruction byte. */
+ long where;
+ /* The relocs associated with the instruction, if any. */
+ fixS *fixp[MAX_RELOC_NUMBER_A_INSN];
+};
+
+#ifndef DEFAULT_ARCH
+#define DEFAULT_ARCH "loongarch64"
+#endif
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. */
+const char comment_chars[] = "#";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output. */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that C style comments are always supported. */
+const char line_comment_chars[] = "#";
+
+/* This array holds machine specific line separator characters. */
+const char line_separator_chars[] = ";";
+
+/* Chars that can be used to separate mant from exp in floating point nums. */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant. */
+/* As in 0f12.456. */
+/* or 0d1.2345e12. */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+const char *md_shortopts = "O::g::G:";
+
+static const char default_arch[] = DEFAULT_ARCH;
+
+enum options
+{
+ OPTION_IGNORE = OPTION_MD_BASE,
+
+ OPTION_ABI,
+ OPTION_FLOAT_ABI,
+
+ OPTION_FLOAT_ISA,
+
+ OPTION_LA_LOCAL_WITH_ABS,
+ OPTION_LA_GLOBAL_WITH_PCREL,
+ OPTION_LA_GLOBAL_WITH_ABS,
+
+ OPTION_END_OF_ENUM,
+};
+
+struct option md_longopts[] =
+{
+ { "mabi", required_argument, NULL, OPTION_ABI },
+ { "mfloat-abi", required_argument, NULL, OPTION_FLOAT_ABI },
+
+ { "mfpu", required_argument, NULL, OPTION_FLOAT_ISA },
+
+ { "mla-local-with-abs", no_argument, NULL, OPTION_LA_LOCAL_WITH_ABS },
+ { "mla-global-with-pcrel", no_argument, NULL, OPTION_LA_GLOBAL_WITH_PCREL },
+ { "mla-global-with-abs", no_argument, NULL, OPTION_LA_GLOBAL_WITH_ABS },
+
+ { NULL, no_argument, NULL, 0 }
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (int c, const char *arg)
+{
+ int ret = 1;
+ switch (c)
+ {
+ case OPTION_ABI:
+ if (strcasecmp (arg, "lp64") == 0)
+ {
+ LARCH_opts.ase_abi |= EF_LOONGARCH_ABI_LP64;
+ LARCH_opts.ase_ilp32 = 1;
+ LARCH_opts.ase_lp64 = 1;
+ }
+ else if (strcasecmp (arg, "ilp32") == 0)
+ {
+ LARCH_opts.ase_abi |= EF_LOONGARCH_ABI_ILP32;
+ LARCH_opts.ase_ilp32 = 1;
+ }
+ else
+ ret = 0;
+ break;
+
+ case OPTION_FLOAT_ABI:
+ if (strcasecmp (arg, "soft") == 0)
+ LARCH_opts.ase_abi |= EF_LOONGARCH_FLOAT_ABI_SOFT;
+ else if (strcasecmp (arg, "single") == 0)
+ LARCH_opts.ase_abi |= EF_LOONGARCH_FLOAT_ABI_SINGLE;
+ else if (strcasecmp (arg, "double") == 0)
+ LARCH_opts.ase_abi |= EF_LOONGARCH_FLOAT_ABI_DOUBLE;
+ else
+ ret = 0;
+ break;
+
+ case OPTION_FLOAT_ISA:
+ if (strcasecmp (arg, "soft") == 0)
+ LARCH_opts.ase_nf = 1;
+ else if (strcasecmp (arg, "single") == 0)
+ LARCH_opts.ase_sf = 1;
+ else if (strcasecmp (arg, "double") == 0)
+ {
+ LARCH_opts.ase_sf = 1;
+ LARCH_opts.ase_df = 1;
+ }
+ else
+ ret = 0;
+ break;
+
+ case OPTION_LA_LOCAL_WITH_ABS:
+ LARCH_opts.ase_labs = 1;
+ break;
+
+ case OPTION_LA_GLOBAL_WITH_PCREL:
+ LARCH_opts.ase_gpcr = 1;
+ break;
+
+ case OPTION_LA_GLOBAL_WITH_ABS:
+ LARCH_opts.ase_gabs = 1;
+ break;
+
+ case OPTION_IGNORE:
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static struct htab *r_htab = NULL;
+static struct htab *f_htab = NULL;
+static struct htab *c_htab = NULL;
+static struct htab *cr_htab = NULL;
+static struct htab *v_htab = NULL;
+static struct htab *x_htab = NULL;
+
+void
+loongarch_after_parse_args ()
+{
+ /* Set default ABI/ISA LP64. */
+ if (!EF_LOONGARCH_IS_LP64(LARCH_opts.ase_abi)
+ && !EF_LOONGARCH_IS_ILP32(LARCH_opts.ase_abi))
+ {
+ if (strcmp (default_arch, "loongarch64") == 0)
+ {
+ LARCH_opts.ase_abi |= EF_LOONGARCH_ABI_LP64;
+ LARCH_opts.ase_ilp32 = 1;
+ LARCH_opts.ase_lp64 = 1;
+ }
+ else if (strcmp (default_arch, "loongarch32") == 0)
+ {
+ LARCH_opts.ase_abi |= EF_LOONGARCH_ABI_ILP32;
+ LARCH_opts.ase_ilp32 = 1;
+ }
+ else
+ as_bad ("unknown default architecture `%s'", default_arch);
+ }
+
+ /* Set default ABI double-float. */
+ if (!EF_LOONGARCH_IS_SOFT_FLOAT(LARCH_opts.ase_abi)
+ && !EF_LOONGARCH_IS_SINGLE_FLOAT(LARCH_opts.ase_abi)
+ && !EF_LOONGARCH_IS_DOUBLE_FLOAT(LARCH_opts.ase_abi))
+ LARCH_opts.ase_abi |= EF_LOONGARCH_FLOAT_ABI_DOUBLE;
+
+ /* Set default ISA double-float. */
+ if (!LARCH_opts.ase_nf
+ && !LARCH_opts.ase_sf
+ && !LARCH_opts.ase_df)
+ {
+ LARCH_opts.ase_sf = 1;
+ LARCH_opts.ase_df = 1;
+ }
+
+ size_t i;
+
+ assert(LARCH_opts.ase_ilp32);
+
+ /* Init ilp32/lp64 registers names. */
+ if (!r_htab)
+ r_htab = str_htab_create (), str_hash_insert (r_htab, "", 0, 0);
+
+ for (i = 0; i < ARRAY_SIZE (loongarch_r_normal_name); i++)
+ str_hash_insert (r_htab, loongarch_r_normal_name[i], (void *) (i + 1), 0);
+
+ if (!cr_htab)
+ cr_htab = str_htab_create (), str_hash_insert (cr_htab, "", 0, 0);
+
+ for (i = 0; i < ARRAY_SIZE (loongarch_cr_normal_name); i++)
+ str_hash_insert (cr_htab, loongarch_cr_normal_name[i], (void *) (i + 1), 0);
+
+ /* Init single/double float registers names. */
+ if (LARCH_opts.ase_sf || LARCH_opts.ase_df)
+ {
+ if (!f_htab)
+ f_htab = str_htab_create (), str_hash_insert (f_htab, "", 0, 0);
+
+ for (i = 0; i < ARRAY_SIZE (loongarch_f_normal_name); i++)
+ str_hash_insert (f_htab, loongarch_f_normal_name[i], (void *) (i + 1),
+ 0);
+
+ if (!c_htab)
+ c_htab = str_htab_create (), str_hash_insert (c_htab, "", 0, 0);
+
+ for (i = 0; i < ARRAY_SIZE (loongarch_c_normal_name); i++)
+ str_hash_insert (c_htab, loongarch_c_normal_name[i], (void *) (i + 1),
+ 0);
+
+ }
+
+ /* Init lsx registers names. */
+ if (LARCH_opts.ase_lsx)
+ {
+ if (!v_htab)
+ v_htab = str_htab_create (), str_hash_insert (v_htab, "", 0, 0);
+ for (i = 0; i < ARRAY_SIZE (loongarch_v_normal_name); i++)
+ str_hash_insert (v_htab, loongarch_v_normal_name[i], (void *) (i + 1),
+ 0);
+ }
+
+ /* Init lasx registers names. */
+ if (LARCH_opts.ase_lasx)
+ {
+ if (!x_htab)
+ x_htab = str_htab_create (), str_hash_insert (x_htab, "", 0, 0);
+ for (i = 0; i < ARRAY_SIZE (loongarch_x_normal_name); i++)
+ str_hash_insert (x_htab, loongarch_x_normal_name[i], (void *) (i + 1),
+ 0);
+ }
+
+ /* Init lp64 registers alias. */
+ if (LARCH_opts.ase_lp64)
+ {
+ for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name); i++)
+ str_hash_insert (r_htab, loongarch_r_lp64_name[i], (void *) (i + 1),
+ 0);
+ for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name1); i++)
+ str_hash_insert (r_htab, loongarch_r_lp64_name1[i], (void *) (i + 1),
+ 0);
+ }
+
+ /* Init float-lp64 registers alias */
+ if ((LARCH_opts.ase_sf || LARCH_opts.ase_df) && LARCH_opts.ase_lp64)
+ {
+ for (i = 0; i < ARRAY_SIZE (loongarch_f_lp64_name); i++)
+ str_hash_insert (f_htab, loongarch_f_lp64_name[i],
+ (void *) (i + 1), 0);
+ for (i = 0; i < ARRAY_SIZE (loongarch_f_lp64_name1); i++)
+ str_hash_insert (f_htab, loongarch_f_lp64_name1[i],
+ (void *) (i + 1), 0);
+ }
+}
+
+const char *
+loongarch_target_format ()
+{
+ return LARCH_opts.ase_lp64 ? "elf64-loongarch" : "elf32-loongarch";
+}
+
+void
+md_begin ()
+{
+ const struct loongarch_opcode *it;
+ struct loongarch_ase *ase;
+ for (ase = loongarch_ASEs; ase->enabled; ase++)
+ for (it = ase->opcodes; it->name; it++)
+ {
+ if (loongarch_check_format (it->format) != 0)
+ as_fatal (_("insn name: %s\tformat: %s\tsyntax error"),
+ it->name, it->format);
+ if (it->mask == 0 && it->macro == 0)
+ as_fatal (_("insn name: %s\nformat: %s\nwe want macro but "
+ "macro is NULL"),
+ it->name, it->format);
+ if (it->macro
+ && loongarch_check_macro (it->format, it->macro) != 0)
+ as_fatal (_("insn name: %s\nformat: %s\nmacro: %s\tsyntax error"),
+ it->name, it->format, it->macro);
+ }
+
+ /* FIXME: expressionS use 'offsetT' as constant,
+ * we want this is 64-bit type. */
+ assert (8 <= sizeof (offsetT));
+}
+
+static const expressionS const_0 = { .X_op = O_constant, .X_add_number = 0 };
+
+static const char *
+my_getExpression (expressionS *ep, const char *str)
+{
+ char *save_in, *ret;
+ save_in = input_line_pointer;
+ input_line_pointer = (char *) str;
+ expression (ep);
+ ret = input_line_pointer;
+ input_line_pointer = save_in;
+ return ret;
+}
+
+static void
+s_loongarch_align (int arg)
+{
+ const char *t = input_line_pointer;
+ while (!is_end_of_line[(unsigned char) *t] && *t != ',')
+ ++t;
+ if (*t == ',')
+ s_align_ptwo (arg);
+ else
+ s_align_ptwo (0);
+}
+
+/* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
+ a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
+ use in DWARF debug information. */
+
+static void
+s_dtprel (int bytes)
+{
+ expressionS ex;
+ char *p;
+
+ expression (&ex);
+
+ if (ex.X_op != O_symbol)
+ {
+ as_bad (_("Unsupported use of %s"),
+ (bytes == 8 ? ".dtpreldword" : ".dtprelword"));
+ ignore_rest_of_line ();
+ }
+
+ p = frag_more (bytes);
+ md_number_to_chars (p, 0, bytes);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
+ (bytes == 8
+ ? BFD_RELOC_LARCH_TLS_DTPREL64
+ : BFD_RELOC_LARCH_TLS_DTPREL32));
+
+ demand_empty_rest_of_line ();
+}
+
+static const pseudo_typeS loongarch_pseudo_table[] =
+{
+ { "align", s_loongarch_align, -4 },
+ { "dword", cons, 8 },
+ { "word", cons, 4 },
+ { "half", cons, 2 },
+ { "dtprelword", s_dtprel, 4 },
+ { "dtpreldword", s_dtprel, 8 },
+ { NULL, NULL, 0 },
+};
+
+void
+loongarch_pop_insert (void)
+{
+ pop_insert (loongarch_pseudo_table);
+}
+
+#define INTERNAL_LABEL_SPECIAL 10
+static unsigned long internal_label_count[INTERNAL_LABEL_SPECIAL] = { 0 };
+
+static const char *
+loongarch_internal_label_name (unsigned long label, int augend)
+{
+ static char symbol_name_build[24];
+ unsigned long want_label;
+ char *p;
+
+ want_label = internal_label_count[label] + augend;
+
+ p = symbol_name_build;
+#ifdef LOCAL_LABEL_PREFIX
+ *p++ = LOCAL_LABEL_PREFIX;
+#endif
+ *p++ = 'L';
+ for (; label; label /= 10)
+ *p++ = label % 10 + '0';
+ /* Make sure internal label never belong to normal label namespace. */
+ *p++ = ':';
+ for (; want_label; want_label /= 10)
+ *p++ = want_label % 10 + '0';
+ *p++ = '\0';
+ return symbol_name_build;
+}
+
+static void
+setup_internal_label_here (unsigned long label)
+{
+ assert (label < INTERNAL_LABEL_SPECIAL);
+ internal_label_count[label]++;
+ colon (loongarch_internal_label_name (label, 0));
+}
+
+void
+get_internal_label (expressionS *label_expr, unsigned long label,
+ int augend /* 0 for previous, 1 for next. */)
+{
+ assert (label < INTERNAL_LABEL_SPECIAL);
+ if (augend == 0 && internal_label_count[label] == 0)
+ as_fatal (_("internal error: we have no internal label yet"));
+ label_expr->X_op = O_symbol;
+ label_expr->X_add_symbol =
+ symbol_find_or_make (loongarch_internal_label_name (label, augend));
+ label_expr->X_add_number = 0;
+}
+
+extern int loongarch_parse_expr (const char *expr,
+ struct reloc_info *reloc_stack_top,
+ size_t max_reloc_num, size_t *reloc_num,
+ offsetT *imm_if_no_reloc);
+
+static int
+is_internal_label (const char *c_str)
+{
+ do
+ {
+ if (*c_str != ':')
+ break;
+ c_str++;
+ if (!('0' <= *c_str && *c_str <= '9'))
+ break;
+ while ('0' <= *c_str && *c_str <= '9')
+ c_str++;
+ if (*c_str != 'b' && *c_str != 'f')
+ break;
+ c_str++;
+ return *c_str == '\0';
+ }
+ while (0);
+ return 0;
+}
+
+static int
+is_label (const char *c_str)
+{
+ if (is_internal_label (c_str))
+ return 1;
+ else if ('0' <= *c_str && *c_str <= '9')
+ {
+ /* [0-9]+[bf] */
+ while ('0' <= *c_str && *c_str <= '9')
+ c_str++;
+ return *c_str == 'b' || *c_str == 'f';
+ }
+ else if (is_name_beginner (*c_str))
+ {
+ /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]* */
+ c_str++;
+ while (is_part_of_name (*c_str))
+ c_str++;
+ return *c_str == '\0';
+ }
+ else
+ return 0;
+}
+
+static int
+is_label_with_addend (const char *c_str)
+{
+ if (is_internal_label (c_str))
+ return 1;
+ else if ('0' <= *c_str && *c_str <= '9')
+ {
+ /* [0-9]+[bf] */
+ while ('0' <= *c_str && *c_str <= '9')
+ c_str++;
+ if (*c_str == 'b' || *c_str == 'f')
+ c_str++;
+ else
+ return 0;
+ return *c_str == '\0'
+ || ((*c_str == '-' || *c_str == '+')
+ && is_unsigned (c_str + 1));
+ }
+ else if (is_name_beginner (*c_str))
+ {
+ /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]* */
+ c_str++;
+ while (is_part_of_name (*c_str))
+ c_str++;
+ return *c_str == '\0'
+ || ((*c_str == '-' || *c_str == '+')
+ && is_unsigned (c_str + 1));
+ }
+ else
+ return 0;
+}
+
+static int32_t
+loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
+ const char *bit_field,
+ const char *arg, void *context)
+{
+ struct loongarch_cl_insn *ip = context;
+ offsetT imm, ret = 0;
+ size_t reloc_num_we_have = MAX_RELOC_NUMBER_A_INSN - ip->reloc_num;
+ size_t reloc_num = 0;
+
+ if (!ip->match_now)
+ return 0;
+
+ switch (esc_ch1)
+ {
+ case 'l':
+ switch (esc_ch2)
+ {
+ default:
+ ip->match_now = is_label (arg);
+ if (!ip->match_now && is_label_with_addend (arg))
+ as_fatal (_("This label shouldn't be with addend."));
+ break;
+ case 'a':
+ ip->match_now = is_label_with_addend (arg);
+ break;
+ }
+ break;
+ case 's':
+ case 'u':
+ ip->match_now =
+ loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num,
+ reloc_num_we_have, &reloc_num, &imm) == 0;
+
+ if (!ip->match_now)
+ break;
+
+ if (esc_ch1 == 's')
+ switch (esc_ch2)
+ {
+ case 'c':
+ ip->match_now = reloc_num == 0;
+ break;
+ }
+ else
+ switch (esc_ch2)
+ {
+ case 'c':
+ ip->match_now = reloc_num == 0 && 0 <= imm;
+ break;
+ }
+
+ if (!ip->match_now)
+ break;
+
+ ret = imm;
+ if (reloc_num)
+ {
+ bfd_reloc_code_real_type reloc_type = BFD_RELOC_NONE;
+ reloc_num_we_have -= reloc_num;
+ if (reloc_num_we_have == 0)
+ as_fatal (_("expr too huge") /* Want one more reloc. */);
+ if (esc_ch1 == 'u')
+ {
+ if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0)
+ reloc_type = BFD_RELOC_LARCH_SOP_POP_32_U_10_12;
+ }
+ else if (esc_ch1 == 's')
+ {
+ if (strncmp (bit_field, "10:16<<2", strlen ("10:16<<2")) == 0)
+ reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2;
+ else if (strncmp (bit_field, "0:5|10:16<<2",
+ strlen ("0:5|10:16<<2")) == 0)
+ reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2;
+ else if (strncmp (bit_field, "0:10|10:16<<2",
+ strlen ("0:10|10:16<<2")) == 0)
+ reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2;
+ else if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0)
+ reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_12;
+ else if (strncmp (bit_field, "5:20", strlen ("5:20")) == 0)
+ reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_5_20;
+ else if (strncmp (bit_field, "10:16", strlen ("10:16")) == 0)
+ reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_16;
+ else if (strncmp (bit_field, "10:5", strlen ("10:5")) == 0)
+ reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_5;
+ }
+ if (reloc_type == BFD_RELOC_NONE)
+ as_fatal (
+ _("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"),
+ esc_ch1, esc_ch2, bit_field, arg);
+ reloc_num++;
+ ip->reloc_num += reloc_num;
+ ip->reloc_info[ip->reloc_num - 1].type = reloc_type;
+ ip->reloc_info[ip->reloc_num - 1].value = const_0;
+ }
+ break;
+ case 'r':
+ imm = (offsetT) str_hash_find (r_htab, arg);
+ ip->match_now = 0 < imm;
+ ret = imm - 1;
+ break;
+ case 'f':
+ imm = (offsetT) str_hash_find (f_htab, arg);
+ ip->match_now = 0 < imm;
+ ret = imm - 1;
+ break;
+ case 'c':
+ switch (esc_ch2)
+ {
+ case 'r':
+ imm = (offsetT) str_hash_find (cr_htab, arg);
+ break;
+ default:
+ imm = (offsetT) str_hash_find (c_htab, arg);
+ }
+ ip->match_now = 0 < imm;
+ ret = imm - 1;
+ break;
+ case 'v':
+ imm = (offsetT) str_hash_find (v_htab, arg);
+ ip->match_now = 0 < imm;
+ ret = imm - 1;
+ break;
+ case 'x':
+ imm = (offsetT) str_hash_find (x_htab, arg);
+ ip->match_now = 0 < imm;
+ ret = imm - 1;
+ break;
+ case '\0':
+ ip->all_match = ip->match_now;
+ ip->insn_length =
+ ip->insn->mask ? loongarch_insn_length (ip->insn->match) : 0;
+ /* FIXME: now we have no relax insn. */
+ ip->relax_max_length = ip->insn_length;
+ break;
+ default:
+ as_fatal (_("unknown escape"));
+ }
+
+ do
+ {
+ /* Check imm overflow. */
+ int bit_width, bits_needed_s, bits_needed_u;
+ char *t;
+
+ if (!ip->match_now)
+ break;
+
+ if (0 < reloc_num)
+ break;
+
+ bit_width = loongarch_get_bit_field_width (bit_field, &t);
+
+ if (bit_width == -1)
+ /* No specify bit width. */
+ break;
+
+ imm = ret;
+ if (t[0] == '<' && t[1] == '<')
+ {
+ int i = strtol (t += 2, &t, 10), j;
+ for (j = i; 0 < j; j--, imm >>= 1)
+ if (imm & 1)
+ as_fatal (_("require imm low %d bit is 0."), i);
+ }
+
+ if (*t == '+')
+ imm -= strtol (t, &t, 10);
+
+ bits_needed_s = loongarch_bits_imm_needed (imm, 1);
+ bits_needed_u = loongarch_bits_imm_needed (imm, 0);
+
+ if ((esc_ch1 == 's' && bit_width < bits_needed_s)
+ || (esc_ch1 != 's' && bit_width < bits_needed_u))
+ /* How to do after we detect overflow. */
+ as_fatal (_("Immediate overflow.\n"
+ "format: %c%c%s\n"
+ "arg: %s"),
+ esc_ch1, esc_ch2, bit_field, arg);
+ }
+ while (0);
+
+ if (esc_ch1 != '\0')
+ {
+ ip->args[ip->arg_num] = ret;
+ ip->arg_num++;
+ }
+ return ret;
+}
+
+static void
+get_loongarch_opcode (struct loongarch_cl_insn *insn)
+{
+ const struct loongarch_opcode *it;
+ struct loongarch_ase *ase;
+ for (ase = loongarch_ASEs; ase->enabled; ase++)
+ {
+ if (!*ase->enabled || (ase->include && !*ase->include)
+ || (ase->exclude && *ase->exclude))
+ continue;
+
+ if (!ase->name_hash_entry)
+ {
+ ase->name_hash_entry = str_htab_create ();
+ for (it = ase->opcodes; it->name; it++)
+ str_hash_insert (ase->name_hash_entry, it->name, (void *) it, 0);
+ }
+
+ if ((it = str_hash_find (ase->name_hash_entry, insn->name)) == NULL)
+ continue;
+
+ do
+ {
+ insn->insn = it;
+ insn->match_now = 1;
+ insn->all_match = 0;
+ insn->arg_num = 0;
+ insn->reloc_num = 0;
+ insn->insn_bin = (loongarch_foreach_args
+ (it->format, insn->arg_strs,
+ loongarch_args_parser_can_match_arg_helper,
+ insn));
+ if (insn->all_match && !(it->include && !*it->include)
+ && !(it->exclude && *it->exclude))
+ {
+ insn->insn_bin |= it->match;
+ return;
+ }
+ it++;
+ }
+ while (it->name && strcasecmp (it->name, insn->name) == 0);
+ }
+}
+
+static int
+check_this_insn_before_appending (struct loongarch_cl_insn *ip)
+{
+ int ret = 0;
+ if (strcmp (ip->name, "la.abs") == 0)
+ {
+ ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_MARK_LA;
+ my_getExpression (&ip->reloc_info[ip->reloc_num].value, ip->arg_strs[1]);
+ ip->reloc_num++;
+ }
+ else if (ip->insn->mask == 0xffff8000
+ /* amswap.w rd, rk, rj */
+ && ((ip->insn_bin & 0xfff00000) == 0x38600000
+ /* ammax_db.wu rd, rk, rj */
+ || (ip->insn_bin & 0xffff0000) == 0x38700000
+ /* ammin_db.wu rd, rk, rj */
+ || (ip->insn_bin & 0xffff0000) == 0x38710000))
+ {
+ /* For AMO insn amswap.[wd], amadd.[wd], etc. */
+ if (ip->args[0] != 0
+ && (ip->args[0] == ip->args[1] || ip->args[0] == ip->args[2]))
+ as_fatal (_("AMO insns require rd != base && rd != rt"
+ " when rd isn't $r0"));
+ }
+ else if ((ip->insn->mask == 0xffe08000
+ /* bstrins.w rd, rj, msbw, lsbw */
+ && (ip->insn_bin & 0xffe00000) == 0x00600000)
+ || (ip->insn->mask == 0xffc00000
+ /* bstrins.d rd, rj, msbd, lsbd */
+ && (ip->insn_bin & 0xff800000) == 0x00800000))
+ {
+ /* For bstr(ins|pick).[wd]. */
+ if (ip->args[2] < ip->args[3])
+ as_fatal (_("bstr(ins|pick).[wd] require msbd >= lsbd"));
+ }
+ else if (ip->insn->mask != 0 && (ip->insn_bin & 0xfe0003c0) == 0x04000000
+ /* csrxchg rd, rj, csr_num */
+ && (strcmp ("csrxchg", ip->name) == 0))
+ as_fatal (_("csrxchg require rj != $r0 && rj != $r1"));
+
+ return ret;
+}
+
+static void
+install_insn (const struct loongarch_cl_insn *insn)
+{
+ char *f = insn->frag->fr_literal + insn->where;
+ if (0 < insn->insn_length)
+ md_number_to_chars (f, insn->insn_bin, insn->insn_length);
+}
+
+static void
+move_insn (struct loongarch_cl_insn *insn, fragS *frag, long where)
+{
+ size_t i;
+ insn->frag = frag;
+ insn->where = where;
+ for (i = 0; i < insn->reloc_num; i++)
+ {
+ insn->fixp[i]->fx_frag = frag;
+ insn->fixp[i]->fx_where = where;
+ }
+ install_insn (insn);
+}
+
+/* Add INSN to the end of the output. */
+static void
+append_fixed_insn (struct loongarch_cl_insn *insn)
+{
+ char *f = frag_more (insn->insn_length);
+ move_insn (insn, frag_now, f - frag_now->fr_literal);
+}
+
+static void
+append_fixp_and_insn (struct loongarch_cl_insn *ip)
+{
+ reloc_howto_type *howto;
+ bfd_reloc_code_real_type reloc_type;
+ struct reloc_info *reloc_info = ip->reloc_info;
+ size_t i;
+ for (i = 0; i < ip->reloc_num; i++)
+ {
+ reloc_type = reloc_info[i].type;
+ howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
+ if (howto == NULL)
+ as_fatal (_("no HOWTO loong relocation number %d"), reloc_type);
+
+ ip->fixp[i] =
+ fix_new_exp (ip->frag, ip->where, bfd_get_reloc_size (howto),
+ &reloc_info[i].value, FALSE, reloc_type);
+ }
+
+ if (ip->insn_length < ip->relax_max_length)
+ as_fatal (_("Internal error: not support relax now"));
+ else
+ append_fixed_insn (ip);
+ dwarf2_emit_insn (0);
+}
+
+/* Ask helper for returning a malloced c_str or NULL. */
+static char *
+assember_macro_helper (const char *const args[], void *context_ptr)
+{
+ struct loongarch_cl_insn *insn = context_ptr;
+ char *ret = NULL;
+ if ( strcmp (insn->name, "li.w") == 0 || strcmp (insn->name, "li.d") == 0)
+ {
+ char args_buf[50], insns_buf[200];
+ const char *arg_strs[6];
+ uint32_t hi32, lo32;
+
+ /* We pay attention to sign extend beacause it is chance of reduce insn.
+ The exception is 12-bit and hi-12-bit unsigned,
+ we need a 'ori' or a 'lu52i.d' accordingly. */
+ char all0_bit_vec, sign_bit_vec, allf_bit_vec, paritial_is_sext_of_prev;
+
+ lo32 = insn->args[1] & 0xffffffff;
+ hi32 = insn->args[1] >> 32;
+
+ if (strcmp (insn->name, "li.w") == 0)
+ {
+ if (hi32 != 0 && hi32 != 0xffffffff)
+ as_fatal (_("li overflow: hi32:0x%x lo32:0x%x"), hi32, lo32);
+ hi32 = lo32 & 0x80000000 ? 0xffffffff : 0;
+ }
+
+ if (strcmp (insn->name, "li.d") == 0 && !LARCH_opts.ase_lp64)
+ as_fatal (_("we can't li.d on 32bit-arch"));
+
+ snprintf (args_buf, sizeof (args_buf), "0x%x,0x%x,0x%x,0x%x,%s",
+ (hi32 >> 20) & 0xfff, hi32 & 0xfffff, (lo32 >> 12) & 0xfffff,
+ lo32 & 0xfff, args[0]);
+ loongarch_split_args_by_comma (args_buf, arg_strs);
+
+ all0_bit_vec =
+ ((((hi32 & 0xfff00000) == 0) << 3) | (((hi32 & 0x000fffff) == 0) << 2)
+ | (((lo32 & 0xfffff000) == 0) << 1) | ((lo32 & 0x00000fff) == 0));
+ sign_bit_vec =
+ ((((hi32 & 0x80000000) != 0) << 3) | (((hi32 & 0x00080000) != 0) << 2)
+ | (((lo32 & 0x80000000) != 0) << 1) | ((lo32 & 0x00000800) != 0));
+ allf_bit_vec =
+ ((((hi32 & 0xfff00000) == 0xfff00000) << 3)
+ | (((hi32 & 0x000fffff) == 0x000fffff) << 2)
+ | (((lo32 & 0xfffff000) == 0xfffff000) << 1)
+ | ((lo32 & 0x00000fff) == 0x00000fff));
+ paritial_is_sext_of_prev =
+ (all0_bit_vec ^ allf_bit_vec) & (all0_bit_vec ^ (sign_bit_vec << 1));
+
+ static const char *const li_32bit[] =
+ {
+ "lu12i.w %5,%3&0x80000?%3-0x100000:%3;ori %5,%5,%4;",
+ "lu12i.w %5,%3&0x80000?%3-0x100000:%3;",
+ "addi.w %5,$r0,%4&0x800?%4-0x1000:%4;",
+ "or %5,$r0,$r0;",
+ };
+ static const char *const li_hi_32bit[] =
+ {
+ "lu32i.d %5,%2&0x80000?%2-0x100000:%2;"
+ "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;",
+ "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;",
+ "lu32i.d %5,%2&0x80000?%2-0x100000:%2;",
+ "",
+ };
+ do
+ {
+ insns_buf[0] = '\0';
+ if (paritial_is_sext_of_prev == 0x7)
+ {
+ strcat (insns_buf, "lu52i.d %5,$r0,%1&0x800?%1-0x1000:%1;");
+ break;
+ }
+ if ((all0_bit_vec & 0x3) == 0x2)
+ strcat (insns_buf, "ori %5,$r0,%4;");
+ else
+ strcat (insns_buf, li_32bit[paritial_is_sext_of_prev & 0x3]);
+ strcat (insns_buf, li_hi_32bit[paritial_is_sext_of_prev >> 2]);
+ }
+ while (0);
+
+ ret = loongarch_expand_macro (insns_buf, arg_strs, NULL, NULL);
+ }
+ return ret;
+}
+
+/* Accept instructions separated by ';'
+ * assuming 'not starting with space and not ending with space' or pass in
+ * empty c_str. */
+static void
+loongarch_assemble_INSNs (char *str)
+{
+ char *rest;
+
+ for (rest = str; *rest != ';' && *rest != '\0'; rest++);
+ if (*rest == ';')
+ *rest++ = '\0';
+
+ if (*str == ':')
+ {
+ str++;
+ setup_internal_label_here (strtol (str, &str, 10));
+ str++;
+ }
+
+ do
+ {
+ if (*str == '\0')
+ break;
+
+ struct loongarch_cl_insn the_one = { 0 };
+ the_one.name = str;
+
+ for (; *str && *str != ' '; str++)
+ ;
+ if (*str == ' ')
+ *str++ = '\0';
+
+ loongarch_split_args_by_comma (str, the_one.arg_strs);
+ get_loongarch_opcode (&the_one);
+
+ if (!the_one.all_match)
+ {
+ char *ss = loongarch_cat_splited_strs (the_one.arg_strs);
+ as_bad (_("no match insn: %s\t%s"), the_one.name, ss ? ss : "");
+ free(ss);
+ return;
+ }
+
+ if (check_this_insn_before_appending (&the_one) != 0)
+ break;
+
+ append_fixp_and_insn (&the_one);
+ if (the_one.insn_length == 0 && the_one.insn->macro)
+ {
+ char *c_str = loongarch_expand_macro (the_one.insn->macro,
+ the_one.arg_strs,
+ assember_macro_helper,
+ &the_one);
+ loongarch_assemble_INSNs (c_str);
+ free (c_str);
+ }
+ }
+ while (0);
+
+ if (*rest != '\0')
+ loongarch_assemble_INSNs (rest);
+}
+
+void
+md_assemble (char *str)
+{
+ loongarch_assemble_INSNs (str);
+}
+
+const char *
+md_atof (int type, char *litP, int *sizeP)
+{
+ return ieee_md_atof (type, litP, sizeP, FALSE);
+}
+
+void
+md_number_to_chars (char *buf, valueT val, int n)
+{
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+long
+md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+void
+md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+{
+ static int64_t stack_top;
+ static int last_reloc_is_sop_push_pcrel_1 = 0;
+ int last_reloc_is_sop_push_pcrel = last_reloc_is_sop_push_pcrel_1;
+ insn_t insn;
+ last_reloc_is_sop_push_pcrel_1 = 0;
+
+ char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL:
+ case BFD_RELOC_LARCH_SOP_PUSH_TLS_GD:
+ case BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT:
+ if (fixP->fx_addsy)
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Relocation against a constant"));
+ break;
+ case BFD_RELOC_LARCH_SOP_PUSH_PCREL:
+ case BFD_RELOC_LARCH_SOP_PUSH_PLT_PCREL:
+ if (fixP->fx_addsy == NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Relocation against a constant"));
+ if (fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_PCREL)
+ {
+ last_reloc_is_sop_push_pcrel_1 = 1;
+ if (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ stack_top = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
+ - (fixP->fx_where + fixP->fx_frag->fr_address));
+ else
+ stack_top = 0;
+ }
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_S_10_5:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if ((stack_top & ~(uint64_t) 0xf) != 0x0
+ && (stack_top & ~(uint64_t) 0xf) != ~(uint64_t) 0xf)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ insn = bfd_getl32 (buf);
+ insn = (insn & (~(uint32_t) 0x7c00)) | ((stack_top & 0x1f) << 10);
+ bfd_putl32 (insn, buf);
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_U_10_12:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if (stack_top & ~(uint64_t) 0xfff)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ insn = bfd_getl32 (buf);
+ insn = (insn & (~(uint32_t) 0x3ffc00)) | ((stack_top & 0xfff) << 10);
+ bfd_putl32 (insn, buf);
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_S_10_12:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if ((stack_top & ~(uint64_t) 0x7ff) != 0x0
+ && (stack_top & ~(uint64_t) 0x7ff) != ~(uint64_t) 0x7ff)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ insn = bfd_getl32 (buf);
+ insn = (insn & (~(uint32_t) 0x3ffc00)) | ((stack_top & 0xfff) << 10);
+ bfd_putl32 (insn, buf);
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_S_10_16:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if ((stack_top & ~(uint64_t) 0x7fff) != 0x0
+ && (stack_top & ~(uint64_t) 0x7fff) != ~(uint64_t) 0x7fff)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ insn = bfd_getl32 (buf);
+ insn = (insn & 0xfc0003ff) | ((stack_top & 0xffff) << 10);
+ bfd_putl32 (insn, buf);
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if ((stack_top & 0x3) != 0)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ stack_top >>= 2;
+ if ((stack_top & ~(uint64_t) 0x7fff) != 0x0
+ && (stack_top & ~(uint64_t) 0x7fff) != ~(uint64_t) 0x7fff)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ insn = bfd_getl32 (buf);
+ insn = (insn & 0xfc0003ff) | ((stack_top & 0xffff) << 10);
+ bfd_putl32 (insn, buf);
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if ((stack_top & 0x3) != 0)
+ break;
+ stack_top >>= 2;
+ if ((stack_top & ~(uint64_t) 0xfffff) != 0x0
+ && (stack_top & ~(uint64_t) 0xfffff) != ~(uint64_t) 0xfffff)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ insn = bfd_getl32 (buf);
+ insn = ((insn & 0xfc0003e0)
+ | ((stack_top & 0xffff) << 10)
+ | ((stack_top & 0x1f0000) >> 16));
+ bfd_putl32 (insn, buf);
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_S_5_20:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if ((stack_top & ~(uint64_t) 0x7ffff) != 0x0
+ && (stack_top & ~(uint64_t) 0x7ffff) != ~(uint64_t) 0x7ffff)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ insn = bfd_getl32 (buf);
+ insn = (insn & (~(uint32_t) 0x1ffffe0)) | ((stack_top & 0xfffff) << 5);
+ bfd_putl32 (insn, buf);
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if ((stack_top & 0x3) != 0)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ stack_top >>= 2;
+ if ((stack_top & ~(uint64_t) 0x1ffffff) != 0x0
+ && (stack_top & ~(uint64_t) 0x1ffffff) != ~(uint64_t) 0x1ffffff)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ insn = bfd_getl32 (buf);
+ insn = ((insn & 0xfc000000)
+ | ((stack_top & 0xffff) << 10)
+ | ((stack_top & 0x3ff0000) >> 16));
+ bfd_putl32 (insn, buf);
+ break;
+
+ case BFD_RELOC_LARCH_SOP_POP_32_U:
+ if (!last_reloc_is_sop_push_pcrel)
+ break;
+ if (stack_top & ~(uint64_t) 0xffffffff)
+ as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
+ bfd_putl32 (stack_top, buf);
+ break;
+
+ case BFD_RELOC_64:
+ case BFD_RELOC_32:
+ if (fixP->fx_subsy)
+ {
+ case BFD_RELOC_24:
+ case BFD_RELOC_16:
+ case BFD_RELOC_8:
+ fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
+ fixP->fx_next->fx_addsy = fixP->fx_subsy;
+ fixP->fx_next->fx_subsy = NULL;
+ fixP->fx_next->fx_offset = 0;
+ fixP->fx_subsy = NULL;
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_64:
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD64;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB64;
+ break;
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD32;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32;
+ break;
+ case BFD_RELOC_24:
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD24;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB24;
+ break;
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
+ break;
+ case BFD_RELOC_8:
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
+ break;
+ default:
+ break;
+ }
+ md_number_to_chars (buf, 0, fixP->fx_size);
+ if (fixP->fx_next->fx_addsy == NULL)
+ fixP->fx_next->fx_done = 1;
+ }
+ if (fixP->fx_addsy == NULL)
+ {
+ fixP->fx_done = 1;
+ md_number_to_chars (buf, *valP, fixP->fx_size);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+int
+loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED,
+ fragS *fragp ATTRIBUTE_UNUSED,
+ long stretch ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
+ asection *segtype ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+arelent *
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
+{
+ arelent *reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->addend = fixp->fx_offset;
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot represent %s relocation in object file"),
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+ return NULL;
+ }
+
+ return reloc;
+}
+
+/* Convert a machine dependent frag. */
+void
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
+ fragS *fragp ATTRIBUTE_UNUSED)
+{
+ /* fragp->fr_fix += 8; */
+}
+
+/* Standard calling conventions leave the CFA at SP on entry. */
+void
+loongarch_cfi_frame_initial_instructions (void)
+{
+ cfi_add_CFA_def_cfa_register (3 /* $sp */);
+}
+
+int
+loongarch_dwarf2_addr_size (void)
+{
+ return LARCH_opts.ase_lp64 ? 8 : 4;
+}
+
+void
+tc_loongarch_parse_to_dw2regnum (expressionS *exp)
+{
+ expression_and_evaluate (exp);
+}
+
+void
+md_show_usage (FILE *stream)
+{
+ fprintf (stream, _("LARCH options:\n"));
+ /* FIXME */
+}
+
+/* Fill in an rs_align_code fragment. We want to fill 'andi $r0,$r0,0'. */
+void
+loongarch_handle_align (fragS *fragp)
+{
+ /* char nop_opcode; */
+ char *p;
+ int bytes, size, excess;
+ valueT opcode;
+
+ if (fragp->fr_type != rs_align_code)
+ return;
+
+ struct loongarch_cl_insn nop =
+ { .name = "andi", .arg_strs = { "$r0", "$r0", "0", NULL } };
+
+ get_loongarch_opcode (&nop);
+ gas_assert (nop.all_match);
+
+ p = fragp->fr_literal + fragp->fr_fix;
+ opcode = nop.insn_bin;
+ size = 4;
+
+ bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+ excess = bytes % size;
+
+ gas_assert (excess < 4);
+ fragp->fr_fix += excess;
+
+ while (excess-- != 0)
+ *p++ = 0;
+
+ md_number_to_chars (p, opcode, size);
+ fragp->fr_var = size;
+}
+
+void
+loongarch_elf_final_processing (void)
+{
+ elf_elfheader (stdoutput)->e_flags |= LARCH_opts.ase_abi;
+}
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
new file mode 100644
index 00000000000..6a076160729
--- /dev/null
+++ b/gas/config/tc-loongarch.h
@@ -0,0 +1,91 @@
+/* tc-loongarch.h -- Header file for tc-loongarch.c.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ Contributed by Loongson Ltd.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the license, or
+ (at your option) any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+#ifndef TC_LOONGARCH
+#define TC_LOONGARCH
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+#define TARGET_ARCH bfd_arch_loongarch
+
+#define WORKING_DOT_WORD 1
+#define REPEAT_CONS_EXPRESSIONS
+
+/* Early than md_begin. */
+#define md_after_parse_args loongarch_after_parse_args
+extern void loongarch_after_parse_args (void);
+
+extern void loongarch_pop_insert (void);
+#define md_pop_insert() loongarch_pop_insert ()
+
+#define TARGET_FORMAT loongarch_target_format ()
+extern const char *loongarch_target_format (void);
+
+#define md_relax_frag(segment, fragp, stretch) \
+ loongarch_relax_frag (segment, fragp, stretch)
+extern int loongarch_relax_frag (asection *, struct frag *, long);
+#define md_section_align(seg, size) (size)
+#define md_undefined_symbol(name) (0)
+#define md_operand(x)
+
+/* This is called to see whether a reloc against a defined symbol
+ should be converted into a reloc against a section. */
+#define tc_fix_adjustable(fixp) 0
+
+/* Values passed to md_apply_fix don't include symbol values. */
+#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1
+#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1
+#define DIFF_EXPR_OK 1
+
+#define TARGET_USE_CFIPOP 1
+#define DWARF2_DEFAULT_RETURN_COLUMN 1 /* $ra. */
+#define DWARF2_CIE_DATA_ALIGNMENT -4
+extern int loongarch_dwarf2_addr_size (void);
+#define DWARF2_FDE_RELOC_SIZE loongarch_dwarf2_addr_size ()
+#define DWARF2_ADDR_SIZE(bfd) loongarch_dwarf2_addr_size ()
+#define CFI_DIFF_EXPR_OK 0
+
+#define tc_cfi_frame_initial_instructions \
+ loongarch_cfi_frame_initial_instructions
+extern void loongarch_cfi_frame_initial_instructions (void);
+
+#define tc_parse_to_dw2regnum tc_loongarch_parse_to_dw2regnum
+extern void tc_loongarch_parse_to_dw2regnum (expressionS *);
+
+/* A enumerated values to specific how to deal with align in '.text'.
+ Now we want to fill 'andi $r0,$r0,0x0'.
+ Here is the type 0, will fill andi insn later. */
+#define NOP_OPCODE (0x00)
+
+#define HANDLE_ALIGN(fragp) loongarch_handle_align (fragp)
+extern void loongarch_handle_align (struct frag *);
+#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
+
+#define elf_tc_final_processing loongarch_elf_final_processing
+extern void loongarch_elf_final_processing (void);
+
+#define MAX_RELOC_NUMBER_A_INSN 20
+
+struct reloc_info
+{
+ bfd_reloc_code_real_type type;
+ expressionS value;
+};
+
+#endif
diff --git a/gas/configure b/gas/configure
index bace2b2f39b..a3d3a7ae255 100755
--- a/gas/configure
+++ b/gas/configure
@@ -12207,6 +12207,23 @@ _ACEOF
using_cgen=yes
;;
+ loongarch)
+ for f in config/loongarch-parse.o config/loongarch-lex-wrapper.o; do
+ case " $extra_objects " in
+ *" $f "*) ;;
+ *) extra_objects="$extra_objects $f" ;;
+ esac
+ done
+ # --target=loongarch[32|64]-*-*. */
+ if test $this_target = $target ; then
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_ARCH "${arch}"
+_ACEOF
+
+ fi
+ ;;
+
m32c)
using_cgen=yes
;;
diff --git a/gas/configure.ac b/gas/configure.ac
index e2374268c56..127f758cb9c 100644
--- a/gas/configure.ac
+++ b/gas/configure.ac
@@ -446,6 +446,19 @@ changequote([,])dnl
using_cgen=yes
;;
+ loongarch)
+ for f in config/loongarch-parse.o config/loongarch-lex-wrapper.o; do
+ case " $extra_objects " in
+ *" $f "*) ;;
+ *) extra_objects="$extra_objects $f" ;;
+ esac
+ done
+ # --target=loongarch[32|64]-*-*. */
+ if test $this_target = $target ; then
+ AC_DEFINE_UNQUOTED(DEFAULT_ARCH, "${arch}", [Default architecture.])
+ fi
+ ;;
+
m32c)
using_cgen=yes
;;
diff --git a/gas/configure.tgt b/gas/configure.tgt
index 550fa4098f8..d3db3aa9e88 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -67,6 +67,8 @@ case ${cpu} in
ip2k) cpu_type=ip2k endian=big ;;
iq2000) cpu_type=iq2000 endian=big ;;
lm32) cpu_type=lm32 ;;
+ loongarch32) cpu_type=loongarch arch=loongarch32;;
+ loongarch64) cpu_type=loongarch arch=loongarch64;;
m32c) cpu_type=m32c endian=little ;;
m32r) cpu_type=m32r endian=big ;;
m32rle) cpu_type=m32r endian=little ;;
@@ -277,6 +279,8 @@ case ${generic_target} in
lm32-*-*) fmt=elf ;;
+ loongarch*) fmt=elf ;;
+
m32c-*-elf) fmt=elf ;;
m32r-*-elf*) fmt=elf ;;
@@ -443,7 +447,7 @@ esac
case ${cpu_type} in
aarch64 | alpha | arm | csky | i386 | ia64 | microblaze | mips | ns32k | \
- or1k | or1knd | pdp11 | ppc | riscv | sh | sparc | z80 | z8k)
+ or1k | or1knd | pdp11 | ppc | riscv | sh | sparc | z80 | z8k | loongarch)
bfd_gas=yes
;;
esac
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index b8d5b9be15e..0cc7455d3ae 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -379,6 +379,11 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
@emph{Target IP2K options:}
[@b{-mip2022}|@b{-mip2022ext}]
@end ifset
+@ifset LOONGARCH
+
+@emph{Target LOONGARCH options:}
+ [@b{-fpic}|@b{-fPIC}|@b{-fno-pic}]
+@end ifset
@ifset M32C
@emph{Target M32C options:}
@@ -1756,6 +1761,25 @@ Assemble for a little endian target.
@end ifset
@c man end
+@ifset LOONGARCH
+
+@ifclear man
+@xref{LoongArch-Options}, for the options available when @value{AS} is configured
+for a LoongArch processor.
+@end ifclear
+
+@ifset man
+@c man begin OPTIONS
+The following options are available when @value{AS} is configured for a
+LoongArch processor.
+@c man end
+@c man begin INCLUDE
+@include c-loongarch.texi
+@c ended inside the included file
+@end ifset
+
+@end ifset
+
@ifset METAG
@ifclear man
@@ -7837,6 +7861,9 @@ subject, see the hardware manufacturer's manual.
@ifset IP2K
* IP2K-Dependent:: IP2K Dependent Features
@end ifset
+@ifset LOONGARCH
+* LoongArch-Dependent:: LoongArch Dependent Features
+@end ifset
@ifset LM32
* LM32-Dependent:: LM32 Dependent Features
@end ifset
@@ -8061,6 +8088,10 @@ family.
@include c-lm32.texi
@end ifset
+@ifset LOONGARCH
+@include c-loongarch.texi
+@end ifset
+
@ifset M32C
@include c-m32c.texi
@end ifset
diff --git a/gas/doc/c-loongarch.texi b/gas/doc/c-loongarch.texi
new file mode 100644
index 00000000000..2a139484577
--- /dev/null
+++ b/gas/doc/c-loongarch.texi
@@ -0,0 +1,39 @@
+@c Copyright (C) 2021 Free Software Foundation, Inc.
+@c This is part of the GAS anual.
+@c For copying conditions, see the file as.texinfo
+@c man end
+
+@ifset GENERIC
+@page
+@node LoongArch-Dependent
+@chapter LoongArch Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter LoongArch Dependent Features
+@end ifclear
+
+@cindex LoongArch support
+@menu
+* LoongArch-Options:: LoongArch Options
+@end menu
+
+@node LoongArch-Options
+@section LoongArch Options
+
+The following table lists all available LoongArch specific options.
+
+@c man begin OPTIONS
+@table @gcctabopt
+
+@cindex @samp{-fpic} option, LoongArch
+@item -fpic
+@itemx -fPIC
+Generate position-independent code
+
+@cindex @samp{-fno-pic} option, LoongArch
+@item -fno-pic
+Don't generate position-independent code (default)
+
+@end table
+@c man end
diff --git a/gas/po/POTFILES.in b/gas/po/POTFILES.in
index 35b4a79472c..c25d4f5023f 100644
--- a/gas/po/POTFILES.in
+++ b/gas/po/POTFILES.in
@@ -87,6 +87,7 @@ config/tc-iq2000.c
config/tc-iq2000.h
config/tc-lm32.c
config/tc-lm32.h
+config/tc-loongarch.c
config/tc-m32c.c
config/tc-m32c.h
config/tc-m32r.c
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index e490d1f20ab..2c812b1fd79 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -73,7 +73,8 @@ if { ![istarget alpha*-*-*vms*]
&& ![istarget riscv*-*-*]
&& ![istarget rl78-*-*]
&& ![istarget rs6000*-*-aix*]
- && ![istarget rx-*-*] } then {
+ && ![istarget rx-*-*]
+ && ![istarget loongarch*-*-*] } then {
gas_test_error "diff1.s" "" "difference of two undefined symbols"
}
@@ -165,9 +166,11 @@ switch -glob $target_triplet {
# symbols on relocs.
setup_xfail "m68hc1*-*-*" "m6811-*-*" "m6812-*-*" "rl78-*-*"
setup_xfail "riscv*-*-*" "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*"
+ setup_xfail "loongarch*-*-*"
run_dump_test redef2
setup_xfail "m68hc1*-*-*" "m6811-*-*" "m6812-*-*" "rl78-*-*"
setup_xfail "riscv*-*-*" "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*"
+ setup_xfail "loongarch*-*-*"
# rs6000-aix disallows redefinition via .comm.
if [is_xcoff_format] {
setup_xfail *-*-*
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index df6b2851c78..16b9b565614 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -178,6 +178,7 @@ if { [is_elf_format] } then {
rl78-*-* { }
riscv*-*-* { }
rx-*-* { }
+ loongarch*-*-* { }
default {
# The next test can fail if the target does not convert fixups
# against ordinary symbols into relocations against section symbols.
diff --git a/gas/testsuite/gas/loongarch/4opt_op.d b/gas/testsuite/gas/loongarch/4opt_op.d
new file mode 100644
index 00000000000..4e8e2cf023c
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/4opt_op.d
@@ -0,0 +1,70 @@
+#as-new:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.text>:
+[ ]+0:[ ]+08118820 [ ]+fmadd.s[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fa3
+[ ]+4:[ ]+08218820 [ ]+fmadd.d[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fa3
+[ ]+8:[ ]+08518820 [ ]+fmsub.s[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fa3
+[ ]+c:[ ]+08618820 [ ]+fmsub.d[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fa3
+[ ]+10:[ ]+08918820 [ ]+fnmadd.s[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fa3
+[ ]+14:[ ]+08a18820 [ ]+fnmadd.d[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fa3
+[ ]+18:[ ]+08d18820 [ ]+fnmsub.s[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fa3
+[ ]+1c:[ ]+08e18820 [ ]+fnmsub.d[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fa3
+[ ]+20:[ ]+0c100820 [ ]+fcmp.caf.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+24:[ ]+0c108820 [ ]+fcmp.saf.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+28:[ ]+0c110820 [ ]+fcmp.clt.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+2c:[ ]+0c118820 [ ]+fcmp.slt.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+30:[ ]+0c118820 [ ]+fcmp.slt.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+34:[ ]+0c120820 [ ]+fcmp.ceq.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+38:[ ]+0c128820 [ ]+fcmp.seq.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+3c:[ ]+0c130820 [ ]+fcmp.cle.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+40:[ ]+0c138820 [ ]+fcmp.sle.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+44:[ ]+0c138820 [ ]+fcmp.sle.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+48:[ ]+0c140820 [ ]+fcmp.cun.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+4c:[ ]+0c148820 [ ]+fcmp.sun.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+50:[ ]+0c150820 [ ]+fcmp.cult.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+54:[ ]+0c150820 [ ]+fcmp.cult.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+58:[ ]+0c158820 [ ]+fcmp.sult.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+5c:[ ]+0c160820 [ ]+fcmp.cueq.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+60:[ ]+0c168820 [ ]+fcmp.sueq.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+64:[ ]+0c170820 [ ]+fcmp.cule.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+68:[ ]+0c170820 [ ]+fcmp.cule.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+6c:[ ]+0c178820 [ ]+fcmp.sule.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+70:[ ]+0c180820 [ ]+fcmp.cne.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+74:[ ]+0c188820 [ ]+fcmp.sne.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+78:[ ]+0c1a0820 [ ]+fcmp.cor.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+7c:[ ]+0c1a8820 [ ]+fcmp.sor.s[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+80:[ ]+0c1c0820 [ ]+fcmp.cune.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+84:[ ]+0c1c8820 [ ]+fcmp.sune.s [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+88:[ ]+0c200820 [ ]+fcmp.caf.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+8c:[ ]+0c208820 [ ]+fcmp.saf.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+90:[ ]+0c210820 [ ]+fcmp.clt.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+94:[ ]+0c218820 [ ]+fcmp.slt.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+98:[ ]+0c218820 [ ]+fcmp.slt.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+9c:[ ]+0c220820 [ ]+fcmp.ceq.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+a0:[ ]+0c228820 [ ]+fcmp.seq.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+a4:[ ]+0c230820 [ ]+fcmp.cle.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+a8:[ ]+0c238820 [ ]+fcmp.sle.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+ac:[ ]+0c238820 [ ]+fcmp.sle.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+b0:[ ]+0c240820 [ ]+fcmp.cun.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+b4:[ ]+0c248820 [ ]+fcmp.sun.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+b8:[ ]+0c250820 [ ]+fcmp.cult.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+bc:[ ]+0c250820 [ ]+fcmp.cult.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+c0:[ ]+0c258820 [ ]+fcmp.sult.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+c4:[ ]+0c260820 [ ]+fcmp.cueq.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+c8:[ ]+0c268820 [ ]+fcmp.sueq.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+cc:[ ]+0c270820 [ ]+fcmp.cule.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+d0:[ ]+0c270820 [ ]+fcmp.cule.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+d4:[ ]+0c278820 [ ]+fcmp.sule.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+d8:[ ]+0c280820 [ ]+fcmp.cne.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+dc:[ ]+0c288820 [ ]+fcmp.sne.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+e0:[ ]+0c2a0820 [ ]+fcmp.cor.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+e4:[ ]+0c2a8820 [ ]+fcmp.sor.d[ ]+[ ]+\$fcc0, \$fa1, \$fa2
+[ ]+e8:[ ]+0c2c0820 [ ]+fcmp.cune.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+ec:[ ]+0c2c8820 [ ]+fcmp.sune.d [ ]+\$fcc0, \$fa1, \$fa2
+[ ]+f0:[ ]+0d000820 [ ]+fsel[ ]+[ ]+\$fa0, \$fa1, \$fa2, \$fcc0
diff --git a/gas/testsuite/gas/loongarch/4opt_op.s b/gas/testsuite/gas/loongarch/4opt_op.s
new file mode 100644
index 00000000000..f14fbd6bad8
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/4opt_op.s
@@ -0,0 +1,61 @@
+fmadd.s $f0,$f1,$f2,$f3
+fmadd.d $f0,$f1,$f2,$f3
+fmsub.s $f0,$f1,$f2,$f3
+fmsub.d $f0,$f1,$f2,$f3
+fnmadd.s $f0,$f1,$f2,$f3
+fnmadd.d $f0,$f1,$f2,$f3
+fnmsub.s $f0,$f1,$f2,$f3
+fnmsub.d $f0,$f1,$f2,$f3
+fcmp.caf.s $fcc0,$f1,$f2
+fcmp.saf.s $fcc0,$f1,$f2
+fcmp.clt.s $fcc0,$f1,$f2
+fcmp.slt.s $fcc0,$f1,$f2
+fcmp.sgt.s $fcc0,$f2,$f1
+fcmp.ceq.s $fcc0,$f1,$f2
+fcmp.seq.s $fcc0,$f1,$f2
+fcmp.cle.s $fcc0,$f1,$f2
+fcmp.sle.s $fcc0,$f1,$f2
+fcmp.sge.s $fcc0,$f2,$f1
+fcmp.cun.s $fcc0,$f1,$f2
+fcmp.sun.s $fcc0,$f1,$f2
+fcmp.cult.s $fcc0,$f1,$f2
+fcmp.cugt.s $fcc0,$f2,$f1
+fcmp.sult.s $fcc0,$f1,$f2
+fcmp.cueq.s $fcc0,$f1,$f2
+fcmp.sueq.s $fcc0,$f1,$f2
+fcmp.cule.s $fcc0,$f1,$f2
+fcmp.cuge.s $fcc0,$f2,$f1
+fcmp.sule.s $fcc0,$f1,$f2
+fcmp.cne.s $fcc0,$f1,$f2
+fcmp.sne.s $fcc0,$f1,$f2
+fcmp.cor.s $fcc0,$f1,$f2
+fcmp.sor.s $fcc0,$f1,$f2
+fcmp.cune.s $fcc0,$f1,$f2
+fcmp.sune.s $fcc0,$f1,$f2
+fcmp.caf.d $fcc0,$f1,$f2
+fcmp.saf.d $fcc0,$f1,$f2
+fcmp.clt.d $fcc0,$f1,$f2
+fcmp.slt.d $fcc0,$f1,$f2
+fcmp.sgt.d $fcc0,$f2,$f1
+fcmp.ceq.d $fcc0,$f1,$f2
+fcmp.seq.d $fcc0,$f1,$f2
+fcmp.cle.d $fcc0,$f1,$f2
+fcmp.sle.d $fcc0,$f1,$f2
+fcmp.sge.d $fcc0,$f2,$f1
+fcmp.cun.d $fcc0,$f1,$f2
+fcmp.sun.d $fcc0,$f1,$f2
+fcmp.cult.d $fcc0,$f1,$f2
+fcmp.cugt.d $fcc0,$f2,$f1
+fcmp.sult.d $fcc0,$f1,$f2
+fcmp.cueq.d $fcc0,$f1,$f2
+fcmp.sueq.d $fcc0,$f1,$f2
+fcmp.cule.d $fcc0,$f1,$f2
+fcmp.cuge.d $fcc0,$f2,$f1
+fcmp.sule.d $fcc0,$f1,$f2
+fcmp.cne.d $fcc0,$f1,$f2
+fcmp.sne.d $fcc0,$f1,$f2
+fcmp.cor.d $fcc0,$f1,$f2
+fcmp.sor.d $fcc0,$f1,$f2
+fcmp.cune.d $fcc0,$f1,$f2
+fcmp.sune.d $fcc0,$f1,$f2
+fsel $f0,$f1,$f2,$fcc0
diff --git a/gas/testsuite/gas/loongarch/fix_op.d b/gas/testsuite/gas/loongarch/fix_op.d
new file mode 100644
index 00000000000..7125f2e3309
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/fix_op.d
@@ -0,0 +1,134 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.text>:
+[ ]+0:[ ]+000010a4 [ ]+clo.w[ ]+[ ]+\$a0, \$a1
+[ ]+4:[ ]+000014a4 [ ]+clz.w[ ]+[ ]+\$a0, \$a1
+[ ]+8:[ ]+000018a4 [ ]+cto.w[ ]+[ ]+\$a0, \$a1
+[ ]+c:[ ]+00001ca4 [ ]+ctz.w[ ]+[ ]+\$a0, \$a1
+[ ]+10:[ ]+000020a4 [ ]+clo.d[ ]+[ ]+\$a0, \$a1
+[ ]+14:[ ]+000024a4 [ ]+clz.d[ ]+[ ]+\$a0, \$a1
+[ ]+18:[ ]+000028a4 [ ]+cto.d[ ]+[ ]+\$a0, \$a1
+[ ]+1c:[ ]+00002ca4 [ ]+ctz.d[ ]+[ ]+\$a0, \$a1
+[ ]+20:[ ]+000030a4 [ ]+revb.2h[ ]+[ ]+\$a0, \$a1
+[ ]+24:[ ]+000034a4 [ ]+revb.4h[ ]+[ ]+\$a0, \$a1
+[ ]+28:[ ]+000038a4 [ ]+revb.2w[ ]+[ ]+\$a0, \$a1
+[ ]+2c:[ ]+00003ca4 [ ]+revb.d[ ]+[ ]+\$a0, \$a1
+[ ]+30:[ ]+000040a4 [ ]+revh.2w[ ]+[ ]+\$a0, \$a1
+[ ]+34:[ ]+000044a4 [ ]+revh.d[ ]+[ ]+\$a0, \$a1
+[ ]+38:[ ]+000048a4 [ ]+bitrev.4b[ ]+[ ]+\$a0, \$a1
+[ ]+3c:[ ]+00004ca4 [ ]+bitrev.8b[ ]+[ ]+\$a0, \$a1
+[ ]+40:[ ]+000050a4 [ ]+bitrev.w[ ]+[ ]+\$a0, \$a1
+[ ]+44:[ ]+000054a4 [ ]+bitrev.d[ ]+[ ]+\$a0, \$a1
+[ ]+48:[ ]+000058a4 [ ]+ext.w.h[ ]+[ ]+\$a0, \$a1
+[ ]+4c:[ ]+00005ca4 [ ]+ext.w.b[ ]+[ ]+\$a0, \$a1
+[ ]+50:[ ]+001500a4 [ ]+move[ ]+[ ]+\$a0, \$a1
+[ ]+54:[ ]+000060a4 [ ]+rdtimel.w[ ]+[ ]+\$a0, \$a1
+[ ]+58:[ ]+000064a4 [ ]+rdtimeh.w[ ]+[ ]+\$a0, \$a1
+[ ]+5c:[ ]+000068a4 [ ]+rdtime.d[ ]+[ ]+\$a0, \$a1
+[ ]+60:[ ]+00006ca4 [ ]+cpucfg[ ]+[ ]+\$a0, \$a1
+[ ]+64:[ ]+000118a0 [ ]+asrtle.d[ ]+[ ]+\$a1, \$a2
+[ ]+68:[ ]+000198a0 [ ]+asrtgt.d[ ]+[ ]+\$a1, \$a2
+[ ]+6c:[ ]+000418a4 [ ]+alsl.w[ ]+[ ]+\$a0, \$a1, \$a2, 0x1
+[ ]+70:[ ]+000598a4 [ ]+alsl.w[ ]+[ ]+\$a0, \$a1, \$a2, 0x4
+[ ]+74:[ ]+000618a4 [ ]+alsl.wu[ ]+[ ]+\$a0, \$a1, \$a2, 0x1
+[ ]+78:[ ]+000798a4 [ ]+alsl.wu[ ]+[ ]+\$a0, \$a1, \$a2, 0x4
+[ ]+7c:[ ]+000818a4 [ ]+bytepick.w[ ]+[ ]+\$a0, \$a1, \$a2, 0x0
+[ ]+80:[ ]+000998a4 [ ]+bytepick.w[ ]+[ ]+\$a0, \$a1, \$a2, 0x3
+[ ]+84:[ ]+000c18a4 [ ]+bytepick.d[ ]+[ ]+\$a0, \$a1, \$a2, 0x0
+[ ]+88:[ ]+000f98a4 [ ]+bytepick.d[ ]+[ ]+\$a0, \$a1, \$a2, 0x7
+[ ]+8c:[ ]+001018a4 [ ]+add.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+90:[ ]+001098a4 [ ]+add.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+94:[ ]+001118a4 [ ]+sub.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+98:[ ]+001198a4 [ ]+sub.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+9c:[ ]+001218a4 [ ]+slt[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+a0:[ ]+001298a4 [ ]+sltu[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+a4:[ ]+001318a4 [ ]+maskeqz[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+a8:[ ]+001398a4 [ ]+masknez[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+ac:[ ]+001418a4 [ ]+nor[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+b0:[ ]+001498a4 [ ]+and[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+b4:[ ]+001518a4 [ ]+or[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+b8:[ ]+001598a4 [ ]+xor[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+bc:[ ]+001618a4 [ ]+orn[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+c0:[ ]+001698a4 [ ]+andn[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+c4:[ ]+001718a4 [ ]+sll.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+c8:[ ]+001798a4 [ ]+srl.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+cc:[ ]+001818a4 [ ]+sra.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+d0:[ ]+001898a4 [ ]+sll.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+d4:[ ]+001918a4 [ ]+srl.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+d8:[ ]+001998a4 [ ]+sra.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+dc:[ ]+001b18a4 [ ]+rotr.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+e0:[ ]+001b98a4 [ ]+rotr.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+e4:[ ]+001c18a4 [ ]+mul.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+e8:[ ]+001c98a4 [ ]+mulh.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+ec:[ ]+001d18a4 [ ]+mulh.wu[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+f0:[ ]+001d98a4 [ ]+mul.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+f4:[ ]+001e18a4 [ ]+mulh.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+f8:[ ]+001e98a4 [ ]+mulh.du[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+fc:[ ]+001f18a4 [ ]+mulw.d.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+100:[ ]+001f98a4 [ ]+mulw.d.wu[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+104:[ ]+002018a4 [ ]+div.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+108:[ ]+002098a4 [ ]+mod.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+10c:[ ]+002118a4 [ ]+div.wu[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+110:[ ]+002198a4 [ ]+mod.wu[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+114:[ ]+002218a4 [ ]+div.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+118:[ ]+002298a4 [ ]+mod.d[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+11c:[ ]+002318a4 [ ]+div.du[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+120:[ ]+002398a4 [ ]+mod.du[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+124:[ ]+002418a4 [ ]+crc.w.b.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+128:[ ]+002498a4 [ ]+crc.w.h.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+12c:[ ]+002518a4 [ ]+crc.w.w.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+130:[ ]+002598a4 [ ]+crc.w.d.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+134:[ ]+002618a4 [ ]+crcc.w.b.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+138:[ ]+002698a4 [ ]+crcc.w.h.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+13c:[ ]+002718a4 [ ]+crcc.w.w.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+140:[ ]+002798a4 [ ]+crcc.w.d.w[ ]+[ ]+\$a0, \$a1, \$a2
+[ ]+144:[ ]+002a0000 [ ]+break[ ]+[ ]+0x0
+[ ]+148:[ ]+002a7fff [ ]+break[ ]+[ ]+0x7fff
+[ ]+14c:[ ]+002a8000 [ ]+dbcl[ ]+[ ]+0x0
+[ ]+150:[ ]+002affff [ ]+dbcl[ ]+[ ]+0x7fff
+[ ]+154:[ ]+002c18a4 [ ]+alsl.d[ ]+[ ]+\$a0, \$a1, \$a2, 0x1
+[ ]+158:[ ]+002d98a4 [ ]+alsl.d[ ]+[ ]+\$a0, \$a1, \$a2, 0x4
+[ ]+15c:[ ]+004080a4 [ ]+slli.w[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+160:[ ]+004084a4 [ ]+slli.w[ ]+[ ]+\$a0, \$a1, 0x1
+[ ]+164:[ ]+0040fca4 [ ]+slli.w[ ]+[ ]+\$a0, \$a1, 0x1f
+[ ]+168:[ ]+004100a4 [ ]+slli.d[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+16c:[ ]+004104a4 [ ]+slli.d[ ]+[ ]+\$a0, \$a1, 0x1
+[ ]+170:[ ]+0041fca4 [ ]+slli.d[ ]+[ ]+\$a0, \$a1, 0x3f
+[ ]+174:[ ]+004480a4 [ ]+srli.w[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+178:[ ]+004484a4 [ ]+srli.w[ ]+[ ]+\$a0, \$a1, 0x1
+[ ]+17c:[ ]+0044fca4 [ ]+srli.w[ ]+[ ]+\$a0, \$a1, 0x1f
+[ ]+180:[ ]+004500a4 [ ]+srli.d[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+184:[ ]+004504a4 [ ]+srli.d[ ]+[ ]+\$a0, \$a1, 0x1
+[ ]+188:[ ]+0045fca4 [ ]+srli.d[ ]+[ ]+\$a0, \$a1, 0x3f
+[ ]+18c:[ ]+004880a4 [ ]+srai.w[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+190:[ ]+004884a4 [ ]+srai.w[ ]+[ ]+\$a0, \$a1, 0x1
+[ ]+194:[ ]+0048fca4 [ ]+srai.w[ ]+[ ]+\$a0, \$a1, 0x1f
+[ ]+198:[ ]+004900a4 [ ]+srai.d[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+19c:[ ]+004904a4 [ ]+srai.d[ ]+[ ]+\$a0, \$a1, 0x1
+[ ]+1a0:[ ]+0049fca4 [ ]+srai.d[ ]+[ ]+\$a0, \$a1, 0x3f
+[ ]+1a4:[ ]+004c80a4 [ ]+rotri.w[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+1a8:[ ]+004c84a4 [ ]+rotri.w[ ]+[ ]+\$a0, \$a1, 0x1
+[ ]+1ac:[ ]+004cfca4 [ ]+rotri.w[ ]+[ ]+\$a0, \$a1, 0x1f
+[ ]+1b0:[ ]+004d00a4 [ ]+rotri.d[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+1b4:[ ]+004d04a4 [ ]+rotri.d[ ]+[ ]+\$a0, \$a1, 0x1
+[ ]+1b8:[ ]+004dfca4 [ ]+rotri.d[ ]+[ ]+\$a0, \$a1, 0x3f
+[ ]+1bc:[ ]+006000a4 [ ]+bstrins.w[ ]+[ ]+\$a0, \$a1, 0x0, 0x0
+[ ]+1c0:[ ]+006204a4 [ ]+bstrins.w[ ]+[ ]+\$a0, \$a1, 0x2, 0x1
+[ ]+1c4:[ ]+007f00a4 [ ]+bstrins.w[ ]+[ ]+\$a0, \$a1, 0x1f, 0x0
+[ ]+1c8:[ ]+006080a4 [ ]+bstrpick.w[ ]+[ ]+\$a0, \$a1, 0x0, 0x0
+[ ]+1cc:[ ]+006284a4 [ ]+bstrpick.w[ ]+[ ]+\$a0, \$a1, 0x2, 0x1
+[ ]+1d0:[ ]+007f80a4 [ ]+bstrpick.w[ ]+[ ]+\$a0, \$a1, 0x1f, 0x0
+[ ]+1d4:[ ]+008000a4 [ ]+bstrins.d[ ]+[ ]+\$a0, \$a1, 0x0, 0x0
+[ ]+1d8:[ ]+009f04a4 [ ]+bstrins.d[ ]+[ ]+\$a0, \$a1, 0x1f, 0x1
+[ ]+1dc:[ ]+00a000a4 [ ]+bstrins.d[ ]+[ ]+\$a0, \$a1, 0x20, 0x0
+[ ]+1e0:[ ]+00bf00a4 [ ]+bstrins.d[ ]+[ ]+\$a0, \$a1, 0x3f, 0x0
+[ ]+1e4:[ ]+00c000a4 [ ]+bstrpick.d[ ]+[ ]+\$a0, \$a1, 0x0, 0x0
+[ ]+1e8:[ ]+00df04a4 [ ]+bstrpick.d[ ]+[ ]+\$a0, \$a1, 0x1f, 0x1
+[ ]+1ec:[ ]+00e000a4 [ ]+bstrpick.d[ ]+[ ]+\$a0, \$a1, 0x20, 0x0
+[ ]+1f0:[ ]+00ff00a4 [ ]+bstrpick.d[ ]+[ ]+\$a0, \$a1, 0x3f, 0x0
diff --git a/gas/testsuite/gas/loongarch/fix_op.s b/gas/testsuite/gas/loongarch/fix_op.s
new file mode 100644
index 00000000000..d0523f959fb
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/fix_op.s
@@ -0,0 +1,125 @@
+clo.w $r4,$r5
+clz.w $r4,$r5
+cto.w $r4,$r5
+ctz.w $r4,$r5
+clo.d $r4,$r5
+clz.d $r4,$r5
+cto.d $r4,$r5
+ctz.d $r4,$r5
+revb.2h $r4,$r5
+revb.4h $r4,$r5
+revb.2w $r4,$r5
+revb.d $r4,$r5
+revh.2w $r4,$r5
+revh.d $r4,$r5
+bitrev.4b $r4,$r5
+bitrev.8b $r4,$r5
+bitrev.w $r4,$r5
+bitrev.d $r4,$r5
+ext.w.h $r4,$r5
+ext.w.b $r4,$r5
+move $r4,$r5
+rdtimel.w $r4,$r5
+rdtimeh.w $r4,$r5
+rdtime.d $r4,$r5
+cpucfg $r4,$r5
+asrtle.d $r5,$r6
+asrtgt.d $r5,$r6
+alsl.w $r4,$r5,$r6,1
+alsl.w $r4,$r5,$r6,4
+alsl.wu $r4,$r5,$r6,1
+alsl.wu $r4,$r5,$r6,4
+bytepick.w $r4,$r5,$r6,0
+bytepick.w $r4,$r5,$r6,3
+bytepick.d $r4,$r5,$r6,0
+bytepick.d $r4,$r5,$r6,7
+add.w $r4,$r5,$r6
+add.d $r4,$r5,$r6
+sub.w $r4,$r5,$r6
+sub.d $r4,$r5,$r6
+slt $r4,$r5,$r6
+sltu $r4,$r5,$r6
+maskeqz $r4,$r5,$r6
+masknez $r4,$r5,$r6
+nor $r4,$r5,$r6
+and $r4,$r5,$r6
+or $r4,$r5,$r6
+xor $r4,$r5,$r6
+orn $r4,$r5,$r6
+andn $r4,$r5,$r6
+sll.w $r4,$r5,$r6
+srl.w $r4,$r5,$r6
+sra.w $r4,$r5,$r6
+sll.d $r4,$r5,$r6
+srl.d $r4,$r5,$r6
+sra.d $r4,$r5,$r6
+rotr.w $r4,$r5,$r6
+rotr.d $r4,$r5,$r6
+mul.w $r4,$r5,$r6
+mulh.w $r4,$r5,$r6
+mulh.wu $r4,$r5,$r6
+mul.d $r4,$r5,$r6
+mulh.d $r4,$r5,$r6
+mulh.du $r4,$r5,$r6
+mulw.d.w $r4,$r5,$r6
+mulw.d.wu $r4,$r5,$r6
+div.w $r4,$r5,$r6
+mod.w $r4,$r5,$r6
+div.wu $r4,$r5,$r6
+mod.wu $r4,$r5,$r6
+div.d $r4,$r5,$r6
+mod.d $r4,$r5,$r6
+div.du $r4,$r5,$r6
+mod.du $r4,$r5,$r6
+crc.w.b.w $r4,$r5,$r6
+crc.w.h.w $r4,$r5,$r6
+crc.w.w.w $r4,$r5,$r6
+crc.w.d.w $r4,$r5,$r6
+crcc.w.b.w $r4,$r5,$r6
+crcc.w.h.w $r4,$r5,$r6
+crcc.w.w.w $r4,$r5,$r6
+crcc.w.d.w $r4,$r5,$r6
+break 0
+break 0x7fff
+dbcl 0
+dbcl 0x7fff
+alsl.d $r4,$r5,$r6,1
+alsl.d $r4,$r5,$r6,4
+slli.w $r4,$r5,0
+slli.w $r4,$r5,1
+slli.w $r4,$r5,0x1f
+slli.d $r4,$r5,0
+slli.d $r4,$r5,1
+slli.d $r4,$r5,0x3f
+srli.w $r4,$r5,0
+srli.w $r4,$r5,1
+srli.w $r4,$r5,0x1f
+srli.d $r4,$r5,0
+srli.d $r4,$r5,1
+srli.d $r4,$r5,0x3f
+srai.w $r4,$r5,0
+srai.w $r4,$r5,1
+srai.w $r4,$r5,0x1f
+srai.d $r4,$r5,0
+srai.d $r4,$r5,1
+srai.d $r4,$r5,0x3f
+rotri.w $r4,$r5,0
+rotri.w $r4,$r5,1
+rotri.w $r4,$r5,0x1f
+rotri.d $r4,$r5,0
+rotri.d $r4,$r5,1
+rotri.d $r4,$r5,0x3f
+bstrins.w $r4,$r5,0,0
+bstrins.w $r4,$r5,2,1
+bstrins.w $r4,$r5,31,0
+bstrpick.w $r4,$r5,0,0
+bstrpick.w $r4,$r5,2,1
+bstrpick.w $r4,$r5,31,0
+bstrins.d $r4,$r5,0,0
+bstrins.d $r4,$r5,31,1
+bstrins.d $r4,$r5,32,0
+bstrins.d $r4,$r5,63,0
+bstrpick.d $r4,$r5,0,0
+bstrpick.d $r4,$r5,31,1
+bstrpick.d $r4,$r5,32,0
+bstrpick.d $r4,$r5,63,0
diff --git a/gas/testsuite/gas/loongarch/float_op.d b/gas/testsuite/gas/loongarch/float_op.d
new file mode 100644
index 00000000000..cdc41d4db8b
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/float_op.d
@@ -0,0 +1,85 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ ]+0:[ ]+01008820 [ ]+fadd.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+4:[ ]+01010820 [ ]+fadd.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+8:[ ]+01028820 [ ]+fsub.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+c:[ ]+01030820 [ ]+fsub.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+10:[ ]+01048820 [ ]+fmul.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+14:[ ]+01050820 [ ]+fmul.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+18:[ ]+01068820 [ ]+fdiv.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+1c:[ ]+01070820 [ ]+fdiv.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+20:[ ]+01088820 [ ]+fmax.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+24:[ ]+01090820 [ ]+fmax.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+28:[ ]+010a8820 [ ]+fmin.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+2c:[ ]+010b0820 [ ]+fmin.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+30:[ ]+010c8820 [ ]+fmaxa.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+34:[ ]+010d0820 [ ]+fmaxa.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+38:[ ]+010e8820 [ ]+fmina.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+3c:[ ]+010f0820 [ ]+fmina.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+40:[ ]+01108820 [ ]+fscaleb.s[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+44:[ ]+01110820 [ ]+fscaleb.d[ ]+[ ]+\$fa0, \$fa1, \$fa2
+[ ]+48:[ ]+01128820 [ ]+fcopysign.s [ ]+\$fa0, \$fa1, \$fa2
+[ ]+4c:[ ]+01130820 [ ]+fcopysign.d [ ]+\$fa0, \$fa1, \$fa2
+[ ]+50:[ ]+01140420 [ ]+fabs.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+54:[ ]+01140820 [ ]+fabs.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+58:[ ]+01141420 [ ]+fneg.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+5c:[ ]+01141820 [ ]+fneg.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+60:[ ]+01142420 [ ]+flogb.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+64:[ ]+01142820 [ ]+flogb.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+68:[ ]+01143420 [ ]+fclass.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+6c:[ ]+01143820 [ ]+fclass.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+70:[ ]+01144420 [ ]+fsqrt.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+74:[ ]+01144820 [ ]+fsqrt.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+78:[ ]+01145420 [ ]+frecip.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+7c:[ ]+01145820 [ ]+frecip.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+80:[ ]+01146420 [ ]+frsqrt.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+84:[ ]+01146820 [ ]+frsqrt.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+88:[ ]+01149420 [ ]+fmov.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+8c:[ ]+01149820 [ ]+fmov.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+90:[ ]+0114a4a0 [ ]+movgr2fr.w[ ]+[ ]+\$fa0, \$a1
+[ ]+94:[ ]+0114a8a0 [ ]+movgr2fr.d[ ]+[ ]+\$fa0, \$a1
+[ ]+98:[ ]+0114aca0 [ ]+movgr2frh.w [ ]+\$fa0, \$a1
+[ ]+9c:[ ]+0114b424 [ ]+movfr2gr.s[ ]+[ ]+\$a0, \$fa1
+[ ]+a0:[ ]+0114b824 [ ]+movfr2gr.d[ ]+[ ]+\$a0, \$fa1
+[ ]+a4:[ ]+0114bc24 [ ]+movfrh2gr.s [ ]+\$a0, \$fa1
+[ ]+a8:[ ]+0114c0a4 [ ]+movgr2fcsr[ ]+[ ]+\$a0, \$a1
+[ ]+ac:[ ]+0114c8a4 [ ]+movfcsr2gr[ ]+[ ]+\$a0, \$a1
+[ ]+b0:[ ]+0114d020 [ ]+movfr2cf[ ]+[ ]+\$fcc0, \$fa1
+[ ]+b4:[ ]+0114d4a0 [ ]+movcf2fr[ ]+[ ]+\$fa0, \$fcc5
+[ ]+b8:[ ]+0114d8a0 [ ]+movgr2cf[ ]+[ ]+\$fcc0, \$a1
+[ ]+bc:[ ]+0114dca4 [ ]+movcf2gr[ ]+[ ]+\$a0, \$fcc5
+[ ]+c0:[ ]+01191820 [ ]+fcvt.s.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+c4:[ ]+01192420 [ ]+fcvt.d.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+c8:[ ]+011a0420 [ ]+ftintrm.w.s [ ]+\$fa0, \$fa1
+[ ]+cc:[ ]+011a0820 [ ]+ftintrm.w.d [ ]+\$fa0, \$fa1
+[ ]+d0:[ ]+011a2420 [ ]+ftintrm.l.s [ ]+\$fa0, \$fa1
+[ ]+d4:[ ]+011a2820 [ ]+ftintrm.l.d [ ]+\$fa0, \$fa1
+[ ]+d8:[ ]+011a4420 [ ]+ftintrp.w.s [ ]+\$fa0, \$fa1
+[ ]+dc:[ ]+011a4820 [ ]+ftintrp.w.d [ ]+\$fa0, \$fa1
+[ ]+e0:[ ]+011a6420 [ ]+ftintrp.l.s [ ]+\$fa0, \$fa1
+[ ]+e4:[ ]+011a6820 [ ]+ftintrp.l.d [ ]+\$fa0, \$fa1
+[ ]+e8:[ ]+011a8420 [ ]+ftintrz.w.s [ ]+\$fa0, \$fa1
+[ ]+ec:[ ]+011a8820 [ ]+ftintrz.w.d [ ]+\$fa0, \$fa1
+[ ]+f0:[ ]+011aa420 [ ]+ftintrz.l.s [ ]+\$fa0, \$fa1
+[ ]+f4:[ ]+011aa820 [ ]+ftintrz.l.d [ ]+\$fa0, \$fa1
+[ ]+f8:[ ]+011ac420 [ ]+ftintrne.w.s[ ]+\$fa0, \$fa1
+[ ]+fc:[ ]+011ac820 [ ]+ftintrne.w.d[ ]+\$fa0, \$fa1
+[ ]+100:[ ]+011ae420 [ ]+ftintrne.l.s[ ]+\$fa0, \$fa1
+[ ]+104:[ ]+011ae820 [ ]+ftintrne.l.d[ ]+\$fa0, \$fa1
+[ ]+108:[ ]+011b0420 [ ]+ftint.w.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+10c:[ ]+011b0820 [ ]+ftint.w.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+110:[ ]+011b2420 [ ]+ftint.l.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+114:[ ]+011b2820 [ ]+ftint.l.d[ ]+[ ]+\$fa0, \$fa1
+[ ]+118:[ ]+011d1020 [ ]+ffint.s.w[ ]+[ ]+\$fa0, \$fa1
+[ ]+11c:[ ]+011d1820 [ ]+ffint.s.l[ ]+[ ]+\$fa0, \$fa1
+[ ]+120:[ ]+011d2020 [ ]+ffint.d.w[ ]+[ ]+\$fa0, \$fa1
+[ ]+124:[ ]+011d2820 [ ]+ffint.d.l[ ]+[ ]+\$fa0, \$fa1
+[ ]+128:[ ]+011e4420 [ ]+frint.s[ ]+[ ]+\$fa0, \$fa1
+[ ]+12c:[ ]+011e4820 [ ]+frint.d[ ]+[ ]+\$fa0, \$fa1
diff --git a/gas/testsuite/gas/loongarch/float_op.s b/gas/testsuite/gas/loongarch/float_op.s
new file mode 100644
index 00000000000..da1a198edee
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/float_op.s
@@ -0,0 +1,76 @@
+fadd.s $f0,$f1,$f2
+fadd.d $f0,$f1,$f2
+fsub.s $f0,$f1,$f2
+fsub.d $f0,$f1,$f2
+fmul.s $f0,$f1,$f2
+fmul.d $f0,$f1,$f2
+fdiv.s $f0,$f1,$f2
+fdiv.d $f0,$f1,$f2
+fmax.s $f0,$f1,$f2
+fmax.d $f0,$f1,$f2
+fmin.s $f0,$f1,$f2
+fmin.d $f0,$f1,$f2
+fmaxa.s $f0,$f1,$f2
+fmaxa.d $f0,$f1,$f2
+fmina.s $f0,$f1,$f2
+fmina.d $f0,$f1,$f2
+fscaleb.s $f0,$f1,$f2
+fscaleb.d $f0,$f1,$f2
+fcopysign.s $f0,$f1,$f2
+fcopysign.d $f0,$f1,$f2
+fabs.s $f0,$f1
+fabs.d $f0,$f1
+fneg.s $f0,$f1
+fneg.d $f0,$f1
+flogb.s $f0,$f1
+flogb.d $f0,$f1
+fclass.s $f0,$f1
+fclass.d $f0,$f1
+fsqrt.s $f0,$f1
+fsqrt.d $f0,$f1
+frecip.s $f0,$f1
+frecip.d $f0,$f1
+frsqrt.s $f0,$f1
+frsqrt.d $f0,$f1
+fmov.s $f0,$f1
+fmov.d $f0,$f1
+movgr2fr.w $f0,$r5
+movgr2fr.d $f0,$r5
+movgr2frh.w $f0,$r5
+movfr2gr.s $r4,$f1
+movfr2gr.d $r4,$f1
+movfrh2gr.s $r4,$f1
+movgr2fcsr $r4,$r5
+movfcsr2gr $r4,$r5
+movfr2cf $fcc0,$f1
+movcf2fr $f0,$fcc5
+movgr2cf $fcc0,$r5
+movcf2gr $r4,$fcc5
+fcvt.s.d $f0,$f1
+fcvt.d.s $f0,$f1
+ftintrm.w.s $f0,$f1
+ftintrm.w.d $f0,$f1
+ftintrm.l.s $f0,$f1
+ftintrm.l.d $f0,$f1
+ftintrp.w.s $f0,$f1
+ftintrp.w.d $f0,$f1
+ftintrp.l.s $f0,$f1
+ftintrp.l.d $f0,$f1
+ftintrz.w.s $f0,$f1
+ftintrz.w.d $f0,$f1
+ftintrz.l.s $f0,$f1
+ftintrz.l.d $f0,$f1
+ftintrne.w.s $f0,$f1
+ftintrne.w.d $f0,$f1
+ftintrne.l.s $f0,$f1
+ftintrne.l.d $f0,$f1
+ftint.w.s $f0,$f1
+ftint.w.d $f0,$f1
+ftint.l.s $f0,$f1
+ftint.l.d $f0,$f1
+ffint.s.w $f0,$f1
+ffint.s.l $f0,$f1
+ffint.d.w $f0,$f1
+ffint.d.l $f0,$f1
+frint.s $f0,$f1
+frint.d $f0,$f1
diff --git a/gas/testsuite/gas/loongarch/imm_op.d b/gas/testsuite/gas/loongarch/imm_op.d
new file mode 100644
index 00000000000..a017aaf5bf7
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/imm_op.d
@@ -0,0 +1,48 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.text>:
+[ ]+0:[ ]+020000a4 [ ]+slti[ ]+[ ]+\$a0, \$a1, 0
+[ ]+4:[ ]+021ffca4 [ ]+slti[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+8:[ ]+022004a4 [ ]+slti[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+c:[ ]+024000a4 [ ]+sltui[ ]+[ ]+\$a0, \$a1, 0
+[ ]+10:[ ]+025ffca4 [ ]+sltui[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+14:[ ]+026004a4 [ ]+sltui[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+18:[ ]+028000a4 [ ]+addi.w[ ]+[ ]+\$a0, \$a1, 0
+[ ]+1c:[ ]+029ffca4 [ ]+addi.w[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+20:[ ]+02a004a4 [ ]+addi.w[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+24:[ ]+02c000a4 [ ]+addi.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+28:[ ]+02dffca4 [ ]+addi.d[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+2c:[ ]+02e004a4 [ ]+addi.d[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+30:[ ]+030000a4 [ ]+lu52i.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+34:[ ]+031ffca4 [ ]+lu52i.d[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+38:[ ]+032004a4 [ ]+lu52i.d[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+3c:[ ]+034000a4 [ ]+andi[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+40:[ ]+035ffca4 [ ]+andi[ ]+[ ]+\$a0, \$a1, 0x7ff
+[ ]+44:[ ]+038000a4 [ ]+ori[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+48:[ ]+039ffca4 [ ]+ori[ ]+[ ]+\$a0, \$a1, 0x7ff
+[ ]+4c:[ ]+03c000a4 [ ]+xori[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+50:[ ]+03dffca4 [ ]+xori[ ]+[ ]+\$a0, \$a1, 0x7ff
+[ ]+54:[ ]+100000a4 [ ]+addu16i.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+58:[ ]+11fffca4 [ ]+addu16i.d[ ]+[ ]+\$a0, \$a1, 32767\(0x7fff\)
+[ ]+5c:[ ]+120004a4 [ ]+addu16i.d[ ]+[ ]+\$a0, \$a1, -32767\(0x8001\)
+[ ]+60:[ ]+14000004 [ ]+lu12i.w[ ]+[ ]+\$a0, 0
+[ ]+64:[ ]+14ffffe4 [ ]+lu12i.w[ ]+[ ]+\$a0, 524287\(0x7ffff\)
+[ ]+68:[ ]+17000024 [ ]+lu32i.d[ ]+[ ]+\$a0, -524287\(0x80001\)
+[ ]+6c:[ ]+18000004 [ ]+pcaddi[ ]+[ ]+\$a0, 0
+[ ]+70:[ ]+18ffffe4 [ ]+pcaddi[ ]+[ ]+\$a0, 524287\(0x7ffff\)
+[ ]+74:[ ]+19000024 [ ]+pcaddi[ ]+[ ]+\$a0, -524287\(0x80001\)
+[ ]+78:[ ]+1a000004 [ ]+pcalau12i[ ]+[ ]+\$a0, 0
+[ ]+7c:[ ]+1affffe4 [ ]+pcalau12i[ ]+[ ]+\$a0, 524287\(0x7ffff\)
+[ ]+80:[ ]+1b000024 [ ]+pcalau12i[ ]+[ ]+\$a0, -524287\(0x80001\)
+[ ]+84:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+88:[ ]+1cffffe4 [ ]+pcaddu12i[ ]+[ ]+\$a0, 524287\(0x7ffff\)
+[ ]+8c:[ ]+1d000024 [ ]+pcaddu12i[ ]+[ ]+\$a0, -524287\(0x80001\)
+[ ]+90:[ ]+1e000004 [ ]+pcaddu18i[ ]+[ ]+\$a0, 0
+[ ]+94:[ ]+1effffe4 [ ]+pcaddu18i[ ]+[ ]+\$a0, 524287\(0x7ffff\)
+[ ]+98:[ ]+1f000024 [ ]+pcaddu18i[ ]+[ ]+\$a0, -524287\(0x80001\)
diff --git a/gas/testsuite/gas/loongarch/imm_op.s b/gas/testsuite/gas/loongarch/imm_op.s
new file mode 100644
index 00000000000..7e1c5518cba
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/imm_op.s
@@ -0,0 +1,39 @@
+slti $r4,$r5,0
+slti $r4,$r5,0x7ff
+slti $r4,$r5,-0x7ff
+sltui $r4,$r5,0
+sltui $r4,$r5,0x7ff
+sltui $r4,$r5,-0x7ff
+addi.w $r4,$r5,0
+addi.w $r4,$r5,0x7ff
+addi.w $r4,$r5,-0x7ff
+addi.d $r4,$r5,0
+addi.d $r4,$r5,0x7ff
+addi.d $r4,$r5,-0x7ff
+lu52i.d $r4,$r5,0
+lu52i.d $r4,$r5,0x7ff
+lu52i.d $r4,$r5,-0x7ff
+andi $r4,$r5,0
+andi $r4,$r5,0x7ff
+ori $r4,$r5,0
+ori $r4,$r5,0x7ff
+xori $r4,$r5,0
+xori $r4,$r5,0x7ff
+addu16i.d $r4,$r5,0
+addu16i.d $r4,$r5,0x7fff
+addu16i.d $r4,$r5,-0x7fff
+lu12i.w $r4,0
+lu12i.w $r4,0x7ffff
+lu32i.d $r4,-0x7ffff
+pcaddi $r4,0
+pcaddi $r4,0x7ffff
+pcaddi $r4,-0x7ffff
+pcalau12i $r4,0
+pcalau12i $r4,0x7ffff
+pcalau12i $r4,-0x7ffff
+pcaddu12i $r4,0
+pcaddu12i $r4,0x7ffff
+pcaddu12i $r4,-0x7ffff
+pcaddu18i $r4,0
+pcaddu18i $r4,0x7ffff
+pcaddu18i $r4,-0x7ffff
diff --git a/gas/testsuite/gas/loongarch/jmp_op.d b/gas/testsuite/gas/loongarch/jmp_op.d
new file mode 100644
index 00000000000..caa61951b4b
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/jmp_op.d
@@ -0,0 +1,68 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.text>:
+[ ]+0:[ ]+03400000 [ ]+andi[ ]+[ ]+\$zero, \$zero, 0x0
+[ ]+4:[ ]+60000004 [ ]+bgtz[ ]+[ ]+\$a0, 0[ ]+# 0x4
+[ ]+[ ]+[ ]+4: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+4: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+8:[ ]+64000080 [ ]+bgez[ ]+[ ]+\$a0, 0[ ]+# 0x8
+[ ]+[ ]+[ ]+8: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+8: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+c:[ ]+64000004 [ ]+blez[ ]+[ ]+\$a0, 0[ ]+# 0xc
+[ ]+[ ]+[ ]+c: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+c: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+10:[ ]+40000080 [ ]+beqz[ ]+[ ]+\$a0, 0[ ]+# 0x10
+[ ]+[ ]+[ ]+10: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+10: R_LARCH_SOP_POP_32_S_0_5_10_16_S2[ ]+\*ABS\*
+[ ]+14:[ ]+44000080 [ ]+bnez[ ]+[ ]+\$a0, 0[ ]+# 0x14
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_POP_32_S_0_5_10_16_S2[ ]+\*ABS\*
+[ ]+18:[ ]+48000000 [ ]+bceqz[ ]+[ ]+\$fcc0, 0[ ]+# 0x18
+[ ]+[ ]+[ ]+18: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+18: R_LARCH_SOP_POP_32_S_0_5_10_16_S2[ ]+\*ABS\*
+[ ]+1c:[ ]+48000100 [ ]+bcnez[ ]+[ ]+\$fcc0, 0[ ]+# 0x1c
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_POP_32_S_0_5_10_16_S2[ ]+\*ABS\*
+[ ]+20:[ ]+4c000080 [ ]+jirl[ ]+[ ]+\$zero, \$a0, 0
+[ ]+24:[ ]+50000000 [ ]+b[ ]+[ ]+0[ ]+# 0x24
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_POP_32_S_0_10_10_16_S2[ ]+\*ABS\*
+[ ]+28:[ ]+54000000 [ ]+bl[ ]+[ ]+0[ ]+# 0x28
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_POP_32_S_0_10_10_16_S2[ ]+\*ABS\*
+[ ]+2c:[ ]+58000085 [ ]+beq[ ]+[ ]+\$a0, \$a1, 0[ ]+# 0x2c
+[ ]+[ ]+[ ]+2c: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+2c: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+30:[ ]+5c000085 [ ]+bne[ ]+[ ]+\$a0, \$a1, 0[ ]+# 0x30
+[ ]+[ ]+[ ]+30: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+30: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+34:[ ]+60000085 [ ]+blt[ ]+[ ]+\$a0, \$a1, 0[ ]+# 0x34
+[ ]+[ ]+[ ]+34: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+34: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+38:[ ]+600000a4 [ ]+blt[ ]+[ ]+\$a1, \$a0, 0[ ]+# 0x38
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+3c:[ ]+64000085 [ ]+bge[ ]+[ ]+\$a0, \$a1, 0[ ]+# 0x3c
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+40:[ ]+640000a4 [ ]+bge[ ]+[ ]+\$a1, \$a0, 0[ ]+# 0x40
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+44:[ ]+68000085 [ ]+bltu[ ]+[ ]+\$a0, \$a1, 0[ ]+# 0x44
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+48:[ ]+680000a4 [ ]+bltu[ ]+[ ]+\$a1, \$a0, 0[ ]+# 0x48
+[ ]+[ ]+[ ]+48: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+48: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+4c:[ ]+6c000085 [ ]+bgeu[ ]+[ ]+\$a0, \$a1, 0[ ]+# 0x4c
+[ ]+[ ]+[ ]+4c: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+4c: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
+[ ]+50:[ ]+6c0000a4 [ ]+bgeu[ ]+[ ]+\$a1, \$a0, 0[ ]+# 0x50
+[ ]+[ ]+[ ]+50: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+50: R_LARCH_SOP_POP_32_S_10_16_S2[ ]+\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/jmp_op.s b/gas/testsuite/gas/loongarch/jmp_op.s
new file mode 100644
index 00000000000..2ec20ed828a
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/jmp_op.s
@@ -0,0 +1,22 @@
+.L1:
+nop
+bgtz $r4,L1
+bgez $r4,L1
+blez $r4,L1
+beqz $r4,L1
+bnez $r4,L1
+bceqz $fcc0,L1
+bcnez $fcc0,L1
+jr $r4
+b L1
+bl L1
+beq $r4,$r5,L1
+bne $r4,$r5,L1
+blt $r4,$r5,L1
+bgt $r4,$r5,L1
+bge $r4,$r5,L1
+ble $r4,$r5,L1
+bltu $r4,$r5,L1
+bgtu $r4,$r5,L1
+bgeu $r4,$r5,L1
+bleu $r4,$r5,L1
diff --git a/gas/testsuite/gas/loongarch/load_store_op.d b/gas/testsuite/gas/loongarch/load_store_op.d
new file mode 100644
index 00000000000..fc15773c1f4
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/load_store_op.d
@@ -0,0 +1,178 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.text>:
+[ ]+0:[ ]+200000a4 [ ]+ll.w[ ]+[ ]+\$a0, \$a1, 0
+[ ]+4:[ ]+203ffca4 [ ]+ll.w[ ]+[ ]+\$a0, \$a1, 16380\(0x3ffc\)
+[ ]+8:[ ]+210000a4 [ ]+sc.w[ ]+[ ]+\$a0, \$a1, 0
+[ ]+c:[ ]+213ffca4 [ ]+sc.w[ ]+[ ]+\$a0, \$a1, 16380\(0x3ffc\)
+[ ]+10:[ ]+220000a4 [ ]+ll.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+14:[ ]+223ffca4 [ ]+ll.d[ ]+[ ]+\$a0, \$a1, 16380\(0x3ffc\)
+[ ]+18:[ ]+230000a4 [ ]+sc.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+1c:[ ]+233ffca4 [ ]+sc.d[ ]+[ ]+\$a0, \$a1, 16380\(0x3ffc\)
+[ ]+20:[ ]+240000a4 [ ]+ldptr.w[ ]+[ ]+\$a0, \$a1, 0
+[ ]+24:[ ]+243ffca4 [ ]+ldptr.w[ ]+[ ]+\$a0, \$a1, 16380\(0x3ffc\)
+[ ]+28:[ ]+250000a4 [ ]+stptr.w[ ]+[ ]+\$a0, \$a1, 0
+[ ]+2c:[ ]+253ffca4 [ ]+stptr.w[ ]+[ ]+\$a0, \$a1, 16380\(0x3ffc\)
+[ ]+30:[ ]+260000a4 [ ]+ldptr.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+34:[ ]+263ffca4 [ ]+ldptr.d[ ]+[ ]+\$a0, \$a1, 16380\(0x3ffc\)
+[ ]+38:[ ]+270000a4 [ ]+stptr.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+3c:[ ]+273ffca4 [ ]+stptr.d[ ]+[ ]+\$a0, \$a1, 16380\(0x3ffc\)
+[ ]+40:[ ]+280000a4 [ ]+ld.b[ ]+[ ]+\$a0, \$a1, 0
+[ ]+44:[ ]+281ffca4 [ ]+ld.b[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+48:[ ]+282004a4 [ ]+ld.b[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+4c:[ ]+284000a4 [ ]+ld.h[ ]+[ ]+\$a0, \$a1, 0
+[ ]+50:[ ]+285ffca4 [ ]+ld.h[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+54:[ ]+286004a4 [ ]+ld.h[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+58:[ ]+288000a4 [ ]+ld.w[ ]+[ ]+\$a0, \$a1, 0
+[ ]+5c:[ ]+289ffca4 [ ]+ld.w[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+60:[ ]+28a004a4 [ ]+ld.w[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+64:[ ]+28c000a4 [ ]+ld.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+68:[ ]+28dffca4 [ ]+ld.d[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+6c:[ ]+28e004a4 [ ]+ld.d[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+70:[ ]+290000a4 [ ]+st.b[ ]+[ ]+\$a0, \$a1, 0
+[ ]+74:[ ]+291ffca4 [ ]+st.b[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+78:[ ]+292004a4 [ ]+st.b[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+7c:[ ]+294000a4 [ ]+st.h[ ]+[ ]+\$a0, \$a1, 0
+[ ]+80:[ ]+295ffca4 [ ]+st.h[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+84:[ ]+296004a4 [ ]+st.h[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+88:[ ]+298000a4 [ ]+st.w[ ]+[ ]+\$a0, \$a1, 0
+[ ]+8c:[ ]+299ffca4 [ ]+st.w[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+90:[ ]+29a004a4 [ ]+st.w[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+94:[ ]+29c000a4 [ ]+st.d[ ]+[ ]+\$a0, \$a1, 0
+[ ]+98:[ ]+29dffca4 [ ]+st.d[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+9c:[ ]+29e004a4 [ ]+st.d[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+a0:[ ]+2a0000a4 [ ]+ld.bu[ ]+[ ]+\$a0, \$a1, 0
+[ ]+a4:[ ]+2a1ffca4 [ ]+ld.bu[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+a8:[ ]+2a2004a4 [ ]+ld.bu[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+ac:[ ]+2a4000a4 [ ]+ld.hu[ ]+[ ]+\$a0, \$a1, 0
+[ ]+b0:[ ]+2a5ffca4 [ ]+ld.hu[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+b4:[ ]+2a6004a4 [ ]+ld.hu[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+b8:[ ]+2a8000a4 [ ]+ld.wu[ ]+[ ]+\$a0, \$a1, 0
+[ ]+bc:[ ]+2a9ffca4 [ ]+ld.wu[ ]+[ ]+\$a0, \$a1, 2047\(0x7ff\)
+[ ]+c0:[ ]+2aa004a4 [ ]+ld.wu[ ]+[ ]+\$a0, \$a1, -2047\(0x801\)
+[ ]+c4:[ ]+2ac000a0 [ ]+preld[ ]+[ ]+0x0, \$a1, 0
+[ ]+c8:[ ]+2adffcbf [ ]+preld[ ]+[ ]+0x1f, \$a1, 2047\(0x7ff\)
+[ ]+cc:[ ]+2ae004bf [ ]+preld[ ]+[ ]+0x1f, \$a1, -2047\(0x801\)
+[ ]+d0:[ ]+2b0000a0 [ ]+fld.s[ ]+[ ]+\$fa0, \$a1, 0
+[ ]+d4:[ ]+2b1ffca0 [ ]+fld.s[ ]+[ ]+\$fa0, \$a1, 2047\(0x7ff\)
+[ ]+d8:[ ]+2b2004a0 [ ]+fld.s[ ]+[ ]+\$fa0, \$a1, -2047\(0x801\)
+[ ]+dc:[ ]+2b4000a0 [ ]+fst.s[ ]+[ ]+\$fa0, \$a1, 0
+[ ]+e0:[ ]+2b5ffca0 [ ]+fst.s[ ]+[ ]+\$fa0, \$a1, 2047\(0x7ff\)
+[ ]+e4:[ ]+2b6004a0 [ ]+fst.s[ ]+[ ]+\$fa0, \$a1, -2047\(0x801\)
+[ ]+e8:[ ]+2b8000a0 [ ]+fld.d[ ]+[ ]+\$fa0, \$a1, 0
+[ ]+ec:[ ]+2b9ffca0 [ ]+fld.d[ ]+[ ]+\$fa0, \$a1, 2047\(0x7ff\)
+[ ]+f0:[ ]+2ba004a0 [ ]+fld.d[ ]+[ ]+\$fa0, \$a1, -2047\(0x801\)
+[ ]+f4:[ ]+2bc000a0 [ ]+fst.d[ ]+[ ]+\$fa0, \$a1, 0
+[ ]+f8:[ ]+2bdffca0 [ ]+fst.d[ ]+[ ]+\$fa0, \$a1, 2047\(0x7ff\)
+[ ]+fc:[ ]+2be004a0 [ ]+fst.d[ ]+[ ]+\$fa0, \$a1, -2047\(0x801\)
+ 100:[ ]+380018a4 [ ]+ldx.b[ ]+[ ]+\$a0, \$a1, \$a2
+ 104:[ ]+380418a4 [ ]+ldx.h[ ]+[ ]+\$a0, \$a1, \$a2
+ 108:[ ]+380818a4 [ ]+ldx.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 10c:[ ]+380c18a4 [ ]+ldx.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 110:[ ]+381018a4 [ ]+stx.b[ ]+[ ]+\$a0, \$a1, \$a2
+ 114:[ ]+381418a4 [ ]+stx.h[ ]+[ ]+\$a0, \$a1, \$a2
+ 118:[ ]+381818a4 [ ]+stx.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 11c:[ ]+381c18a4 [ ]+stx.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 120:[ ]+382018a4 [ ]+ldx.bu[ ]+[ ]+\$a0, \$a1, \$a2
+ 124:[ ]+382418a4 [ ]+ldx.hu[ ]+[ ]+\$a0, \$a1, \$a2
+ 128:[ ]+382818a4 [ ]+ldx.wu[ ]+[ ]+\$a0, \$a1, \$a2
+ 12c:[ ]+382c18a0 [ ]+preldx[ ]+[ ]+0x0, \$a1, \$a2
+ 130:[ ]+382c18bf [ ]+preldx[ ]+[ ]+0x1f, \$a1, \$a2
+ 134:[ ]+38720000 [ ]+dbar[ ]+[ ]+0x0
+ 138:[ ]+38727fff [ ]+dbar[ ]+[ ]+0x7fff
+ 13c:[ ]+38728000 [ ]+ibar[ ]+[ ]+0x0
+ 140:[ ]+3872ffff [ ]+ibar[ ]+[ ]+0x7fff
+ 144:[ ]+386014c4 [ ]+amswap.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 148:[ ]+386018a4 [ ]+amswap.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 14c:[ ]+386094c4 [ ]+amswap.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 150:[ ]+386098a4 [ ]+amswap.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 154:[ ]+386114c4 [ ]+amadd.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 158:[ ]+386118a4 [ ]+amadd.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 15c:[ ]+386194c4 [ ]+amadd.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 160:[ ]+386198a4 [ ]+amadd.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 164:[ ]+386214c4 [ ]+amand.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 168:[ ]+386218a4 [ ]+amand.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 16c:[ ]+386294c4 [ ]+amand.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 170:[ ]+386298a4 [ ]+amand.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 174:[ ]+386314c4 [ ]+amor.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 178:[ ]+386318a4 [ ]+amor.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 17c:[ ]+386394c4 [ ]+amor.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 180:[ ]+386398a4 [ ]+amor.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 184:[ ]+386414c4 [ ]+amxor.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 188:[ ]+386418a4 [ ]+amxor.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 18c:[ ]+386494c4 [ ]+amxor.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 190:[ ]+386498a4 [ ]+amxor.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 194:[ ]+386514c4 [ ]+ammax.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 198:[ ]+386518a4 [ ]+ammax.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 19c:[ ]+386594c4 [ ]+ammax.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 1a0:[ ]+386598a4 [ ]+ammax.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 1a4:[ ]+386614c4 [ ]+ammin.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 1a8:[ ]+386618a4 [ ]+ammin.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 1ac:[ ]+386694c4 [ ]+ammin.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 1b0:[ ]+386698a4 [ ]+ammin.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 1b4:[ ]+386714c4 [ ]+ammax.wu[ ]+[ ]+\$a0, \$a1, \$a2
+ 1b8:[ ]+386718a4 [ ]+ammax.wu[ ]+[ ]+\$a0, \$a2, \$a1
+ 1bc:[ ]+386794c4 [ ]+ammax.du[ ]+[ ]+\$a0, \$a1, \$a2
+ 1c0:[ ]+386798a4 [ ]+ammax.du[ ]+[ ]+\$a0, \$a2, \$a1
+ 1c4:[ ]+386814c4 [ ]+ammin.wu[ ]+[ ]+\$a0, \$a1, \$a2
+ 1c8:[ ]+386818a4 [ ]+ammin.wu[ ]+[ ]+\$a0, \$a2, \$a1
+ 1cc:[ ]+386894c4 [ ]+ammin.du[ ]+[ ]+\$a0, \$a1, \$a2
+ 1d0:[ ]+386898a4 [ ]+ammin.du[ ]+[ ]+\$a0, \$a2, \$a1
+ 1d4:[ ]+386914c4 [ ]+amswap_db.w [ ]+\$a0, \$a1, \$a2
+ 1d8:[ ]+386918a4 [ ]+amswap_db.w [ ]+\$a0, \$a2, \$a1
+ 1dc:[ ]+386994c4 [ ]+amswap_db.d [ ]+\$a0, \$a1, \$a2
+ 1e0:[ ]+386998a4 [ ]+amswap_db.d [ ]+\$a0, \$a2, \$a1
+ 1e4:[ ]+386a14c4 [ ]+amadd_db.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 1e8:[ ]+386a18a4 [ ]+amadd_db.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 1ec:[ ]+386a94c4 [ ]+amadd_db.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 1f0:[ ]+386a98a4 [ ]+amadd_db.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 1f4:[ ]+386b14c4 [ ]+amand_db.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 1f8:[ ]+386b18a4 [ ]+amand_db.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 1fc:[ ]+386b94c4 [ ]+amand_db.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 200:[ ]+386b98a4 [ ]+amand_db.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 204:[ ]+386c14c4 [ ]+amor_db.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 208:[ ]+386c18a4 [ ]+amor_db.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 20c:[ ]+386c94c4 [ ]+amor_db.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 210:[ ]+386c98a4 [ ]+amor_db.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 214:[ ]+386d14c4 [ ]+amxor_db.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 218:[ ]+386d18a4 [ ]+amxor_db.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 21c:[ ]+386d94c4 [ ]+amxor_db.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 220:[ ]+386d98a4 [ ]+amxor_db.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 224:[ ]+386e14c4 [ ]+ammax_db.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 228:[ ]+386e18a4 [ ]+ammax_db.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 22c:[ ]+386e94c4 [ ]+ammax_db.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 230:[ ]+386e98a4 [ ]+ammax_db.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 234:[ ]+386f14c4 [ ]+ammin_db.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 238:[ ]+386f18a4 [ ]+ammin_db.w[ ]+[ ]+\$a0, \$a2, \$a1
+ 23c:[ ]+386f94c4 [ ]+ammin_db.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 240:[ ]+386f98a4 [ ]+ammin_db.d[ ]+[ ]+\$a0, \$a2, \$a1
+ 244:[ ]+387014c4 [ ]+ammax_db.wu [ ]+\$a0, \$a1, \$a2
+ 248:[ ]+387018a4 [ ]+ammax_db.wu [ ]+\$a0, \$a2, \$a1
+ 24c:[ ]+387094c4 [ ]+ammax_db.du [ ]+\$a0, \$a1, \$a2
+ 250:[ ]+387098a4 [ ]+ammax_db.du [ ]+\$a0, \$a2, \$a1
+ 254:[ ]+387114c4 [ ]+ammin_db.wu [ ]+\$a0, \$a1, \$a2
+ 258:[ ]+387118a4 [ ]+ammin_db.wu [ ]+\$a0, \$a2, \$a1
+ 25c:[ ]+387194c4 [ ]+ammin_db.du [ ]+\$a0, \$a1, \$a2
+ 260:[ ]+387198a4 [ ]+ammin_db.du [ ]+\$a0, \$a2, \$a1
+ 264:[ ]+387818a4 [ ]+ldgt.b[ ]+[ ]+\$a0, \$a1, \$a2
+ 268:[ ]+387898a4 [ ]+ldgt.h[ ]+[ ]+\$a0, \$a1, \$a2
+ 26c:[ ]+387918a4 [ ]+ldgt.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 270:[ ]+387998a4 [ ]+ldgt.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 274:[ ]+387a18a4 [ ]+ldle.b[ ]+[ ]+\$a0, \$a1, \$a2
+ 278:[ ]+387a98a4 [ ]+ldle.h[ ]+[ ]+\$a0, \$a1, \$a2
+ 27c:[ ]+387b18a4 [ ]+ldle.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 280:[ ]+387b98a4 [ ]+ldle.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 284:[ ]+387c18a4 [ ]+stgt.b[ ]+[ ]+\$a0, \$a1, \$a2
+ 288:[ ]+387c98a4 [ ]+stgt.h[ ]+[ ]+\$a0, \$a1, \$a2
+ 28c:[ ]+387d18a4 [ ]+stgt.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 290:[ ]+387d98a4 [ ]+stgt.d[ ]+[ ]+\$a0, \$a1, \$a2
+ 294:[ ]+387e18a4 [ ]+stle.b[ ]+[ ]+\$a0, \$a1, \$a2
+ 298:[ ]+387e98a4 [ ]+stle.h[ ]+[ ]+\$a0, \$a1, \$a2
+ 29c:[ ]+387f18a4 [ ]+stle.w[ ]+[ ]+\$a0, \$a1, \$a2
+ 2a0:[ ]+387f98a4 [ ]+stle.d[ ]+[ ]+\$a0, \$a1, \$a2
diff --git a/gas/testsuite/gas/loongarch/load_store_op.s b/gas/testsuite/gas/loongarch/load_store_op.s
new file mode 100644
index 00000000000..efbd124a29c
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/load_store_op.s
@@ -0,0 +1,169 @@
+ll.w $r4,$r5,0
+ll.w $r4,$r5,0x3ffc
+sc.w $r4,$r5,0
+sc.w $r4,$r5,0x3ffc
+ll.d $r4,$r5,0
+ll.d $r4,$r5,0x3ffc
+sc.d $r4,$r5,0
+sc.d $r4,$r5,0x3ffc
+ldptr.w $r4,$r5,0
+ldptr.w $r4,$r5,0x3ffc
+stptr.w $r4,$r5,0
+stptr.w $r4,$r5,0x3ffc
+ldptr.d $r4,$r5,0
+ldptr.d $r4,$r5,0x3ffc
+stptr.d $r4,$r5,0
+stptr.d $r4,$r5,0x3ffc
+ld.b $r4,$r5,0
+ld.b $r4,$r5,0x7ff
+ld.b $r4,$r5,-0x7ff
+ld.h $r4,$r5,0
+ld.h $r4,$r5,0x7ff
+ld.h $r4,$r5,-0x7ff
+ld.w $r4,$r5,0
+ld.w $r4,$r5,0x7ff
+ld.w $r4,$r5,-0x7ff
+ld.d $r4,$r5,0
+ld.d $r4,$r5,0x7ff
+ld.d $r4,$r5,-0x7ff
+st.b $r4,$r5,0
+st.b $r4,$r5,0x7ff
+st.b $r4,$r5,-0x7ff
+st.h $r4,$r5,0
+st.h $r4,$r5,0x7ff
+st.h $r4,$r5,-0x7ff
+st.w $r4,$r5,0
+st.w $r4,$r5,0x7ff
+st.w $r4,$r5,-0x7ff
+st.d $r4,$r5,0
+st.d $r4,$r5,0x7ff
+st.d $r4,$r5,-0x7ff
+ld.bu $r4,$r5,0
+ld.bu $r4,$r5,0x7ff
+ld.bu $r4,$r5,-0x7ff
+ld.hu $r4,$r5,0
+ld.hu $r4,$r5,0x7ff
+ld.hu $r4,$r5,-0x7ff
+ld.wu $r4,$r5,0
+ld.wu $r4,$r5,0x7ff
+ld.wu $r4,$r5,-0x7ff
+preld 0,$r5,0
+preld 31,$r5,0x7ff
+preld 31,$r5,-0x7ff
+fld.s $f0,$r5,0
+fld.s $f0,$r5,0x7ff
+fld.s $f0,$r5,-0x7ff
+fst.s $f0,$r5,0
+fst.s $f0,$r5,0x7ff
+fst.s $f0,$r5,-0x7ff
+fld.d $f0,$r5,0
+fld.d $f0,$r5,0x7ff
+fld.d $f0,$r5,-0x7ff
+fst.d $f0,$r5,0
+fst.d $f0,$r5,0x7ff
+fst.d $f0,$r5,-0x7ff
+ldx.b $r4,$r5,$r6
+ldx.h $r4,$r5,$r6
+ldx.w $r4,$r5,$r6
+ldx.d $r4,$r5,$r6
+stx.b $r4,$r5,$r6
+stx.h $r4,$r5,$r6
+stx.w $r4,$r5,$r6
+stx.d $r4,$r5,$r6
+ldx.bu $r4,$r5,$r6
+ldx.hu $r4,$r5,$r6
+ldx.wu $r4,$r5,$r6
+preldx 0,$r5,$r6
+preldx 31,$r5,$r6
+dbar 0
+dbar 0x7fff
+ibar 0
+ibar 0x7fff
+amswap.w $r4,$r5,$r6,0
+amswap.w $r4,$r6,$r5
+amswap.d $r4,$r5,$r6,0
+amswap.d $r4,$r6,$r5
+amadd.w $r4,$r5,$r6,0
+amadd.w $r4,$r6,$r5
+amadd.d $r4,$r5,$r6,0
+amadd.d $r4,$r6,$r5
+amand.w $r4,$r5,$r6,0
+amand.w $r4,$r6,$r5
+amand.d $r4,$r5,$r6,0
+amand.d $r4,$r6,$r5
+amor.w $r4,$r5,$r6,0
+amor.w $r4,$r6,$r5
+amor.d $r4,$r5,$r6,0
+amor.d $r4,$r6,$r5
+amxor.w $r4,$r5,$r6,0
+amxor.w $r4,$r6,$r5
+amxor.d $r4,$r5,$r6,0
+amxor.d $r4,$r6,$r5
+ammax.w $r4,$r5,$r6,0
+ammax.w $r4,$r6,$r5
+ammax.d $r4,$r5,$r6,0
+ammax.d $r4,$r6,$r5
+ammin.w $r4,$r5,$r6,0
+ammin.w $r4,$r6,$r5
+ammin.d $r4,$r5,$r6,0
+ammin.d $r4,$r6,$r5
+ammax.wu $r4,$r5,$r6,0
+ammax.wu $r4,$r6,$r5
+ammax.du $r4,$r5,$r6,0
+ammax.du $r4,$r6,$r5
+ammin.wu $r4,$r5,$r6,0
+ammin.wu $r4,$r6,$r5
+ammin.du $r4,$r5,$r6,0
+ammin.du $r4,$r6,$r5
+amswap_db.w $r4,$r5,$r6,0
+amswap_db.w $r4,$r6,$r5
+amswap_db.d $r4,$r5,$r6,0
+amswap_db.d $r4,$r6,$r5
+amadd_db.w $r4,$r5,$r6,0
+amadd_db.w $r4,$r6,$r5
+amadd_db.d $r4,$r5,$r6,0
+amadd_db.d $r4,$r6,$r5
+amand_db.w $r4,$r5,$r6,0
+amand_db.w $r4,$r6,$r5
+amand_db.d $r4,$r5,$r6,0
+amand_db.d $r4,$r6,$r5
+amor_db.w $r4,$r5,$r6,0
+amor_db.w $r4,$r6,$r5
+amor_db.d $r4,$r5,$r6,0
+amor_db.d $r4,$r6,$r5
+amxor_db.w $r4,$r5,$r6,0
+amxor_db.w $r4,$r6,$r5
+amxor_db.d $r4,$r5,$r6,0
+amxor_db.d $r4,$r6,$r5
+ammax_db.w $r4,$r5,$r6,0
+ammax_db.w $r4,$r6,$r5
+ammax_db.d $r4,$r5,$r6,0
+ammax_db.d $r4,$r6,$r5
+ammin_db.w $r4,$r5,$r6,0
+ammin_db.w $r4,$r6,$r5
+ammin_db.d $r4,$r5,$r6,0
+ammin_db.d $r4,$r6,$r5
+ammax_db.wu $r4,$r5,$r6,0
+ammax_db.wu $r4,$r6,$r5
+ammax_db.du $r4,$r5,$r6,0
+ammax_db.du $r4,$r6,$r5
+ammin_db.wu $r4,$r5,$r6,0
+ammin_db.wu $r4,$r6,$r5
+ammin_db.du $r4,$r5,$r6,0
+ammin_db.du $r4,$r6,$r5
+ldgt.b $r4,$r5,$r6
+ldgt.h $r4,$r5,$r6
+ldgt.w $r4,$r5,$r6
+ldgt.d $r4,$r5,$r6
+ldle.b $r4,$r5,$r6
+ldle.h $r4,$r5,$r6
+ldle.w $r4,$r5,$r6
+ldle.d $r4,$r5,$r6
+stgt.b $r4,$r5,$r6
+stgt.h $r4,$r5,$r6
+stgt.w $r4,$r5,$r6
+stgt.d $r4,$r5,$r6
+stle.b $r4,$r5,$r6
+stle.h $r4,$r5,$r6
+stle.w $r4,$r5,$r6
+stle.d $r4,$r5,$r6
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
new file mode 100644
index 00000000000..c186b67315f
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
@@ -0,0 +1,23 @@
+# Expect script for LoongArch assembler tests.
+# Copyright (C) 2021 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+if [istarget loongarch*-*-*] {
+ run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+}
diff --git a/gas/testsuite/gas/loongarch/macro_op.d b/gas/testsuite/gas/loongarch/macro_op.d
new file mode 100644
index 00000000000..fabd006b8c1
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/macro_op.d
@@ -0,0 +1,733 @@
+#as:
+#objdump: -dr
+#skip: loongarch32*-*-*
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0000000000000000 <.text>:
+[ ]+0:[ ]+00150004 [ ]+move[ ]+[ ]+\$a0, \$zero
+[ ]+4:[ ]+02bffc04 [ ]+addi.w[ ]+[ ]+\$a0, \$zero, -1\(0xfff\)
+[ ]+8:[ ]+00150004 [ ]+move[ ]+[ ]+\$a0, \$zero
+[ ]+c:[ ]+02bffc04 [ ]+addi.w[ ]+[ ]+\$a0, \$zero, -1\(0xfff\)
+[ ]+10:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+10: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x800
+[ ]+[ ]+[ ]+10: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+10: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+10: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+14:[ ]+28c00084 [ ]+ld.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x804
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+14: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+18:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+18: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x800
+[ ]+[ ]+[ ]+18: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+18: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+18: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+18: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+18: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+1c:[ ]+28c00084 [ ]+ld.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x804
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+1c: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+20:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000000
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+20: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+24:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000004
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+24: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+28:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000008
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+28: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+2c:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+2c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x8000000c
+[ ]+[ ]+[ ]+2c: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+2c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+2c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+2c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+2c: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+30:[ ]+380c1484 [ ]+ldx.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+34:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+34: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x800
+[ ]+[ ]+[ ]+34: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+34: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+34: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+34: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+34: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+38:[ ]+28c00084 [ ]+ld.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x804
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+38: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+3c:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000000
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+3c: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+40:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000004
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+40: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+44:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000008
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+44: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+48:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+48: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x8000000c
+[ ]+[ ]+[ ]+48: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+48: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+48: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+48: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+48: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+4c:[ ]+380c1484 [ ]+ldx.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+50:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+50: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x800
+[ ]+[ ]+[ ]+50: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+50: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+50: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+50: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+50: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+54:[ ]+28c00084 [ ]+ld.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x804
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+54: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+58:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000000
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+58: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+5c:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000004
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+5c: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+60:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+60: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000008
+[ ]+[ ]+[ ]+60: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+60: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+60: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+60: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+60: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+60: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+60: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+64:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+64: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x8000000c
+[ ]+[ ]+[ ]+64: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+64: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+64: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+64: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+64: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+68:[ ]+380c1484 [ ]+ldx.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+6c:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+6c: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x800
+[ ]+[ ]+[ ]+6c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+6c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+6c: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+70:[ ]+02c00084 [ ]+addi.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+70: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x4
+[ ]+[ ]+[ ]+70: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x804
+[ ]+[ ]+[ ]+70: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+70: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+70: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+70: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+70: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+70: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+74:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000000
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+74: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+78:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x4
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000004
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+78: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+7c:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+7c: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000008
+[ ]+[ ]+[ ]+7c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+7c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+7c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+7c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+7c: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+80:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+80: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x8000000c
+[ ]+[ ]+[ ]+80: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+80: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+80: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+84:[ ]+00109484 [ ]+add.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+88:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+88: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x800
+[ ]+[ ]+[ ]+88: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+88: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+88: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+8c:[ ]+02c00084 [ ]+addi.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+8c: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x4
+[ ]+[ ]+[ ]+8c: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x804
+[ ]+[ ]+[ ]+8c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+8c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+8c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+8c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+8c: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+8c: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+90:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000000
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+90: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+94:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x4
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000004
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+94: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+98:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+98: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000008
+[ ]+[ ]+[ ]+98: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+98: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+98: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+98: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+98: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+9c:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+9c: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x8000000c
+[ ]+[ ]+[ ]+9c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+9c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+9c: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+a0:[ ]+00109484 [ ]+add.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+a4:[ ]+14000004 [ ]+lu12i.w[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+a4: R_LARCH_MARK_LA[ ]+L1
+[ ]+[ ]+[ ]+a4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+L1
+[ ]+[ ]+[ ]+a4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+a4: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+a4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+a4: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+a4: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+a8:[ ]+03800084 [ ]+ori[ ]+[ ]+\$a0, \$a0, 0x0
+[ ]+[ ]+[ ]+a8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+L1
+[ ]+[ ]+[ ]+a8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+a8: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+a8: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+ac:[ ]+16000004 [ ]+lu32i.d[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+ac: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+L1
+[ ]+[ ]+[ ]+ac: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+ac: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+ac: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+ac: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+ac: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+b0:[ ]+03000084 [ ]+lu52i.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+b0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+L1
+[ ]+[ ]+[ ]+b0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+b0: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+b0: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+b4:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+b4: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x800
+[ ]+[ ]+[ ]+b4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+b4: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+b4: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+b8:[ ]+02c00084 [ ]+addi.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+b8: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x4
+[ ]+[ ]+[ ]+b8: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x804
+[ ]+[ ]+[ ]+b8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+b8: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+b8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+b8: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+b8: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+b8: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+bc:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+bc: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x800
+[ ]+[ ]+[ ]+bc: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+bc: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+bc: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+c0:[ ]+02c00084 [ ]+addi.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+c0: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x4
+[ ]+[ ]+[ ]+c0: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x804
+[ ]+[ ]+[ ]+c0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+c0: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+c0: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c0: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c0: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+c4:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_PUSH_PCREL[ ]+L1
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000000
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c4: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+c8:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x4
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000004
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+c8: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+cc:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+cc: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x80000008
+[ ]+[ ]+[ ]+cc: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+cc: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+cc: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+cc: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+cc: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+d0:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+d0: R_LARCH_SOP_PUSH_PCREL[ ]+L1\+0x8000000c
+[ ]+[ ]+[ ]+d0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+d0: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+d0: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+d4:[ ]+00109484 [ ]+add.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+d8:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+d8: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x800
+[ ]+[ ]+[ ]+d8: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+d8: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+d8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+d8: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+d8: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+dc:[ ]+28c00084 [ ]+ld.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x804
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+dc: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+e0:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000000
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e0: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+e4:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000004
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e4: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+e8:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+e8: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000008
+[ ]+[ ]+[ ]+e8: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+e8: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+e8: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+e8: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+e8: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+ec:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+ec: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x8000000c
+[ ]+[ ]+[ ]+ec: R_LARCH_SOP_PUSH_GPREL[ ]+L1
+[ ]+[ ]+[ ]+ec: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+ec: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+ec: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+ec: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+f0:[ ]+380c1484 [ ]+ldx.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+f4:[ ]+14000004 [ ]+lu12i.w[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+f4: R_LARCH_SOP_PUSH_TLS_TPREL[ ]+L1
+[ ]+[ ]+[ ]+f4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+f4: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+f4: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+f4: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+f4: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+f8:[ ]+03800084 [ ]+ori[ ]+[ ]+\$a0, \$a0, 0x0
+[ ]+[ ]+[ ]+f8: R_LARCH_SOP_PUSH_TLS_TPREL[ ]+L1
+[ ]+[ ]+[ ]+f8: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+f8: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+f8: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+fc:[ ]+16000004 [ ]+lu32i.d[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+fc: R_LARCH_SOP_PUSH_TLS_TPREL[ ]+L1
+[ ]+[ ]+[ ]+fc: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+fc: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+fc: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+fc: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+fc: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+100:[ ]+03000084 [ ]+lu52i.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+100: R_LARCH_SOP_PUSH_TLS_TPREL[ ]+L1
+[ ]+[ ]+[ ]+100: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+100: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+100: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+104:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+104: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x800
+[ ]+[ ]+[ ]+104: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+104: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+104: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+104: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+104: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+108:[ ]+28c00084 [ ]+ld.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x804
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+108: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+10c:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000000
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+10c: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+110:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000004
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+110: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+114:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+114: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000008
+[ ]+[ ]+[ ]+114: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+114: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+114: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+114: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+114: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+114: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+114: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+118:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+118: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x8000000c
+[ ]+[ ]+[ ]+118: R_LARCH_SOP_PUSH_TLS_GOT[ ]+L1
+[ ]+[ ]+[ ]+118: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+118: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+118: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+118: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+11c:[ ]+380c1484 [ ]+ldx.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+120:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+120: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x800
+[ ]+[ ]+[ ]+120: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+120: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+120: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+120: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+120: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+124:[ ]+02c00084 [ ]+addi.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x804
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+124: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+128:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000000
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+128: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+12c:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000004
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+12c: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+130:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+130: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000008
+[ ]+[ ]+[ ]+130: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+130: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+130: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+130: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+130: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+130: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+130: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+134:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+134: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x8000000c
+[ ]+[ ]+[ ]+134: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+134: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+134: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+134: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+134: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+138:[ ]+00109484 [ ]+add.d[ ]+[ ]+\$a0, \$a0, \$a1
+[ ]+13c:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+13c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x800
+[ ]+[ ]+[ ]+13c: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+13c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+13c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+13c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+13c: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+140:[ ]+02c00084 [ ]+addi.d[ ]+[ ]+\$a0, \$a0, 0
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x804
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+140: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+144:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000000
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+144: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+148:[ ]+03800005 [ ]+ori[ ]+[ ]+\$a1, \$zero, 0x0
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x4
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000004
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x20
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_SUB[ ]+\*ABS\*
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xfff
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_AND[ ]+\*ABS\*
+[ ]+[ ]+[ ]+148: R_LARCH_SOP_POP_32_U_10_12[ ]+\*ABS\*
+[ ]+14c:[ ]+16000005 [ ]+lu32i.d[ ]+[ ]+\$a1, 0
+[ ]+[ ]+[ ]+14c: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x80000008
+[ ]+[ ]+[ ]+14c: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+14c: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+14c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0xc
+[ ]+[ ]+[ ]+14c: R_LARCH_SOP_SL[ ]+\*ABS\*
+[ ]+[ ]+[ ]+14c: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x2c
+[ ]+[ ]+[ ]+14c: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+14c: R_LARCH_SOP_POP_32_S_5_20[ ]+\*ABS\*
+[ ]+150:[ ]+030000a5 [ ]+lu52i.d[ ]+[ ]+\$a1, \$a1, 0
+[ ]+[ ]+[ ]+150: R_LARCH_SOP_PUSH_PCREL[ ]+_GLOBAL_OFFSET_TABLE_\+0x8000000c
+[ ]+[ ]+[ ]+150: R_LARCH_SOP_PUSH_TLS_GD[ ]+L1
+[ ]+[ ]+[ ]+150: R_LARCH_SOP_ADD[ ]+\*ABS\*
+[ ]+[ ]+[ ]+150: R_LARCH_SOP_PUSH_ABSOLUTE[ ]+\*ABS\*\+0x34
+[ ]+[ ]+[ ]+150: R_LARCH_SOP_SR[ ]+\*ABS\*
+[ ]+[ ]+[ ]+150: R_LARCH_SOP_POP_32_S_10_12[ ]+\*ABS\*
+[ ]+154:[ ]+00109484 [ ]+add.d[ ]+[ ]+\$a0, \$a0, \$a1
diff --git a/gas/testsuite/gas/loongarch/macro_op.s b/gas/testsuite/gas/loongarch/macro_op.s
new file mode 100644
index 00000000000..d83261f55f0
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/macro_op.s
@@ -0,0 +1,29 @@
+.L1:
+li.w $r4,0
+li.w $r4,0xffffffff
+li.d $r4,0
+li.d $r4,0xffffffffffffffff
+la $r4,L1
+la.global $r4,L1
+la.global $r4,$r5,L1
+la.global $r4,L1
+la.global $r4,$r5,L1
+la.global $r4,L1
+la.global $r4,$r5,L1
+la.local $r4,L1
+la.local $r4,$r5,L1
+la.local $r4,L1
+la.local $r4,$r5,L1
+la.abs $r4,L1
+la.pcrel $r4,L1
+la.pcrel $r4,L1
+la.pcrel $r4,$r5,L1
+la.got $r4,L1
+la.got $r4,$r5,L1
+la.tls.le $r4,L1
+la.tls.ie $r4,L1
+la.tls.ie $r4,$r5,L1
+la.tls.ld $r4,L1
+la.tls.ld $r4,$r5,L1
+la.tls.gd $r4,L1
+la.tls.gd $r4,$r5,L1
diff --git a/gas/testsuite/gas/loongarch/nop.d b/gas/testsuite/gas/loongarch/nop.d
new file mode 100644
index 00000000000..4cdcc5ce0d2
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/nop.d
@@ -0,0 +1,10 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+0:[ ]+03400000[ ]+andi[ ]+\$zero, \$zero, 0x0
diff --git a/gas/testsuite/gas/loongarch/nop.s b/gas/testsuite/gas/loongarch/nop.s
new file mode 100644
index 00000000000..99456883315
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/nop.s
@@ -0,0 +1,2 @@
+target:
+ nop
diff --git a/gas/testsuite/gas/loongarch/privilege_op.d b/gas/testsuite/gas/loongarch/privilege_op.d
new file mode 100644
index 00000000000..12d4790a027
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/privilege_op.d
@@ -0,0 +1,44 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.text>:
+[ ]+0:[ ]+04000004 [ ]+csrrd[ ]+[ ]+\$a0, 0x0
+[ ]+4:[ ]+04fffc04 [ ]+csrrd[ ]+[ ]+\$a0, 0x3fff
+[ ]+8:[ ]+04000024 [ ]+csrwr[ ]+[ ]+\$a0, 0x0
+[ ]+c:[ ]+04fffc24 [ ]+csrwr[ ]+[ ]+\$a0, 0x3fff
+[ ]+10:[ ]+040000a4 [ ]+csrxchg[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+14:[ ]+04fffca4 [ ]+csrxchg[ ]+[ ]+\$a0, \$a1, 0x3fff
+[ ]+18:[ ]+060000a0 [ ]+cacop[ ]+[ ]+0x0, \$a1, 0
+[ ]+1c:[ ]+060000bf [ ]+cacop[ ]+[ ]+0x1f, \$a1, 0
+[ ]+20:[ ]+061ffca0 [ ]+cacop[ ]+[ ]+0x0, \$a1, 2047\(0x7ff\)
+[ ]+24:[ ]+061ffcbf [ ]+cacop[ ]+[ ]+0x1f, \$a1, 2047\(0x7ff\)
+[ ]+28:[ ]+062004a0 [ ]+cacop[ ]+[ ]+0x0, \$a1, -2047\(0x801\)
+[ ]+2c:[ ]+062004bf [ ]+cacop[ ]+[ ]+0x1f, \$a1, -2047\(0x801\)
+[ ]+30:[ ]+064000a4 [ ]+lddir[ ]+[ ]+\$a0, \$a1, 0x0
+[ ]+34:[ ]+0643fca4 [ ]+lddir[ ]+[ ]+\$a0, \$a1, 0xff
+[ ]+38:[ ]+064400a0 [ ]+ldpte[ ]+[ ]+\$a1, 0x0
+[ ]+3c:[ ]+0647fca0 [ ]+ldpte[ ]+[ ]+\$a1, 0xff
+[ ]+40:[ ]+064800a4 [ ]+iocsrrd.b[ ]+[ ]+\$a0, \$a1
+[ ]+44:[ ]+064804a4 [ ]+iocsrrd.h[ ]+[ ]+\$a0, \$a1
+[ ]+48:[ ]+064808a4 [ ]+iocsrrd.w[ ]+[ ]+\$a0, \$a1
+[ ]+4c:[ ]+06480ca4 [ ]+iocsrrd.d[ ]+[ ]+\$a0, \$a1
+[ ]+50:[ ]+064810a4 [ ]+iocsrwr.b[ ]+[ ]+\$a0, \$a1
+[ ]+54:[ ]+064814a4 [ ]+iocsrwr.h[ ]+[ ]+\$a0, \$a1
+[ ]+58:[ ]+064818a4 [ ]+iocsrwr.w[ ]+[ ]+\$a0, \$a1
+[ ]+5c:[ ]+06481ca4 [ ]+iocsrwr.d[ ]+[ ]+\$a0, \$a1
+[ ]+60:[ ]+06482000 [ ]+tlbclr[ ]+
+[ ]+64:[ ]+06482400 [ ]+tlbflush[ ]+
+[ ]+68:[ ]+06482800 [ ]+tlbsrch[ ]+
+[ ]+6c:[ ]+06482c00 [ ]+tlbrd[ ]+
+[ ]+70:[ ]+06483000 [ ]+tlbwr[ ]+
+[ ]+74:[ ]+06483400 [ ]+tlbfill[ ]+
+[ ]+78:[ ]+06483800 [ ]+ertn[ ]+
+[ ]+7c:[ ]+06488000 [ ]+idle[ ]+[ ]+0x0
+[ ]+80:[ ]+0648ffff [ ]+idle[ ]+[ ]+0x7fff
+[ ]+84:[ ]+064998a0 [ ]+invtlb[ ]+[ ]+0x0, \$a1, \$a2
+[ ]+88:[ ]+064998bf [ ]+invtlb[ ]+[ ]+0x1f, \$a1, \$a2
diff --git a/gas/testsuite/gas/loongarch/privilege_op.s b/gas/testsuite/gas/loongarch/privilege_op.s
new file mode 100644
index 00000000000..cdc357324f1
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/privilege_op.s
@@ -0,0 +1,35 @@
+csrrd $r4,0
+csrrd $r4,0x3fff
+csrwr $r4,0
+csrwr $r4,0x3fff
+csrxchg $r4,$r5,0
+csrxchg $r4,$r5,0x3fff
+cacop 0,$r5,0
+cacop 0x1f,$r5,0
+cacop 0,$r5,0x7ff
+cacop 0x1f,$r5,0x7ff
+cacop 0,$r5,-0x7ff
+cacop 0x1f,$r5,-0x7ff
+lddir $r4,$r5,0
+lddir $r4,$r5,0xff
+ldpte $r5,0
+ldpte $r5,0xff
+iocsrrd.b $r4,$r5
+iocsrrd.h $r4,$r5
+iocsrrd.w $r4,$r5
+iocsrrd.d $r4,$r5
+iocsrwr.b $r4,$r5
+iocsrwr.h $r4,$r5
+iocsrwr.w $r4,$r5
+iocsrwr.d $r4,$r5
+tlbclr
+tlbflush
+tlbsrch
+tlbrd
+tlbwr
+tlbfill
+ertn
+idle 0
+idle 0x7fff
+invtlb 0,$r5,$r6
+invtlb 0x1f,$r5,$r6
diff --git a/gas/testsuite/gas/loongarch/syscall.d b/gas/testsuite/gas/loongarch/syscall.d
new file mode 100644
index 00000000000..1625664f57b
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/syscall.d
@@ -0,0 +1,11 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.text>:
+[ ]+0:[ ]+002b0000 [ ]+syscall[ ]+[ ]+0x0
+[ ]+4:[ ]+002b7fff [ ]+syscall[ ]+[ ]+0x7fff
diff --git a/gas/testsuite/gas/loongarch/syscall.s b/gas/testsuite/gas/loongarch/syscall.s
new file mode 100644
index 00000000000..168b713f20c
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/syscall.s
@@ -0,0 +1,2 @@
+syscall 0
+syscall 0x7fff
diff --git a/gas/testsuite/lib/gas-defs.exp b/gas/testsuite/lib/gas-defs.exp
index f9ee6f4ac72..6074c2ee282 100644
--- a/gas/testsuite/lib/gas-defs.exp
+++ b/gas/testsuite/lib/gas-defs.exp
@@ -360,6 +360,10 @@ proc verbose_eval { expr { level 1 } } {
# This definition is taken from an unreleased version of DejaGnu. Once
# that version gets released, and has been out in the world for a few
# months at least, it may be safe to delete this copy.
+
+if { [istarget loongarch*-*-*] } {
+ rename prune_warnings prune_warnings_other
+}
if ![string length [info proc prune_warnings]] {
#
# prune_warnings -- delete various system verbosities from TEXT.