aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAndrew Jenner <andrew@codesourcery.com>2018-07-30 12:24:14 +0100
committerNick Clifton <nickc@redhat.com>2018-07-30 12:24:14 +0100
commitb8891f8d622a31306062065813fc278d8a94fe21 (patch)
tree4476440b69e1ce90b7e2b5a90d08f42563b43a7a /gas
parent7d8a31665739412395f6dd370d2279acd322e78e (diff)
downloadgdb-b8891f8d622a31306062065813fc278d8a94fe21.zip
gdb-b8891f8d622a31306062065813fc278d8a94fe21.tar.gz
gdb-b8891f8d622a31306062065813fc278d8a94fe21.tar.bz2
Add support for the C_SKY series of processors.
This patch series is a new binutils port for C-SKY processors, including support for both the V1 and V2 processor variants. V1 is derived from the MCore architecture while V2 is substantially different, with mixed 16- and 32-bit instructions, a larger register set, a different (but overlapping) ABI, etc. There is support for bare-metal ELF targets and Linux with both glibc and uClibc. This code is being contributed jointly by C-SKY Microsystems and Mentor Graphics. C-SKY is responsible for the technical content and has proposed Lifang Xia and Yunhai Shang as port maintainers. (Note that C-SKY does have a corporate copyright assignment on file with the FSF.) Mentor Graphics' role has been cleaning up the code, adding documentation and additional test cases, etc, to address issues we anticipated reviewers would complain about. bfd * Makefile.am (ALL_MACHINES, ALL_MACHINES_CFILES): Add C-SKY. (BFD32_BACKENDS, BFD_BACKENDS_CFILES): Likewise. * Makefile.in: Regenerated. * archures.c (enum bfd_architecture): Add bfd_arch_csky and related bfd_mach defines. (bfd_csky_arch): Declare. (bfd_archures_list): Add C-SKY. * bfd-in.h (elf32_csky_build_stubs): Declare. (elf32_csky_size_stubs): Declare. (elf32_csky_next_input_section: Declare. (elf32_csky_setup_section_lists): Declare. * bfd-in2.h: Regenerated. * config.bfd: Add C-SKY. * configure.ac: Likewise. * configure: Regenerated. * cpu-csky.c: New file. * elf-bfd.h (enum elf_target_id): Add C-SKY. * elf32-csky.c: New file. * libbfd.h: Regenerated. * reloc.c: Add C-SKY relocations. * targets.c (csky_elf32_be_vec, csky_elf32_le_vec): Declare. (_bfd_target_vector): Add C-SKY target vector entries. binutils* readelf.c: Include elf/csky.h. (guess_is_rela): Handle EM_CSKY. (dump_relocations): Likewise. (get_machine_name): Likewise. (is_32bit_abs_reloc): Likewise. include * dis-asm.h (csky_symbol_is_valid): Declare. * opcode/csky.h: New file. opcodes * Makefile.am (TARGET_LIBOPCODES_CFILES): Add csky-dis.c. * Makefile.in: Regenerated. * configure.ac: Add C-SKY. * configure: Regenerated. * csky-dis.c: New file. * csky-opc.h: New file. * disassemble.c (ARCH_csky): Define. (disassembler, disassemble_init_for_target): Add case for ARCH_csky. * disassemble.h (print_insn_csky, csky_get_disassembler): Declare. gas * Makefile.am (TARGET_CPU_CFILES): Add entry for C-SKY. (TARGET_CPU_HFILES, TARGET_ENV_HFILES): Likewise. * Makefile.in: Regenerated. * config/tc-csky.c: New file. * config/tc-csky.h: New file. * config/te-csky_abiv1.h: New file. * config/te-csky_abiv1_linux.h: New file. * config/te-csky_abiv2.h: New file. * config/te-csky_abiv2_linux.h: New file. * configure.tgt: Add C-SKY. * doc/Makefile.am (CPU_DOCS): Add entry for C-SKY. * doc/Makefile.in: Regenerated. * doc/all.texi: Set CSKY feature. * doc/as.texi (Overview): Add C-SKY options. (Machine Dependencies): Likewise. * doc/c-csky.texi: New file. * testsuite/gas/csky/*: New test cases. ld * Makefile.am (ALL_EMULATION_SOURCES): Add C-SKY emulations. (ecskyelf.c, ecskyelf_linux.c): New rules. * Makefile.in: Regenerated. * configure.tgt: Add C-SKY. * emulparams/cskyelf.sh: New file. * emulparams/cskyelf_linux.sh: New file. * emultempl/cskyelf.em: New file. * gen-doc.texi: Add C-SKY. * ld.texi: Likewise. (Options specific to C-SKY targets): New section. * testsuite/ld-csky/*: New tests.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog21
-rw-r--r--gas/Makefile.am6
-rw-r--r--gas/Makefile.in9
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/tc-csky.c7299
-rw-r--r--gas/config/tc-csky.h107
-rw-r--r--gas/config/te-csky_abiv1.h24
-rw-r--r--gas/config/te-csky_abiv1_linux.h24
-rw-r--r--gas/config/te-csky_abiv2.h26
-rw-r--r--gas/config/te-csky_abiv2_linux.h24
-rw-r--r--gas/configure.tgt7
-rw-r--r--gas/doc/Makefile.am1
-rw-r--r--gas/doc/Makefile.in1
-rw-r--r--gas/doc/all.texi1
-rw-r--r--gas/doc/as.texi46
-rw-r--r--gas/doc/c-csky.texi195
-rw-r--r--gas/testsuite/gas/csky/801_relax.d14
-rw-r--r--gas/testsuite/gas/csky/801_relax.s16
-rw-r--r--gas/testsuite/gas/csky/802j.d13
-rw-r--r--gas/testsuite/gas/csky/802j.s7
-rw-r--r--gas/testsuite/gas/csky/all.d150
-rw-r--r--gas/testsuite/gas/csky/all.s132
-rw-r--r--gas/testsuite/gas/csky/bsr1.d12
-rw-r--r--gas/testsuite/gas/csky/bsr1.s6
-rw-r--r--gas/testsuite/gas/csky/bsr2.d9
-rw-r--r--gas/testsuite/gas/csky/bsr2.s3
-rw-r--r--gas/testsuite/gas/csky/csky.exp7
-rw-r--r--gas/testsuite/gas/csky/csky_vdsp.d364
-rw-r--r--gas/testsuite/gas/csky/csky_vdsp.s359
-rw-r--r--gas/testsuite/gas/csky/cskyv2_all.d325
-rw-r--r--gas/testsuite/gas/csky/cskyv2_all.s316
-rw-r--r--gas/testsuite/gas/csky/cskyv2_dsp.d18
-rw-r--r--gas/testsuite/gas/csky/cskyv2_dsp.s11
-rw-r--r--gas/testsuite/gas/csky/cskyv2_elrw.d10
-rw-r--r--gas/testsuite/gas/csky/cskyv2_elrw.s6
-rw-r--r--gas/testsuite/gas/csky/cskyv2_float.d59
-rw-r--r--gas/testsuite/gas/csky/cskyv2_float.s52
-rw-r--r--gas/testsuite/gas/csky/cskyv2_lrw.d19
-rw-r--r--gas/testsuite/gas/csky/cskyv2_lrw.s11
-rw-r--r--gas/testsuite/gas/csky/cskyv2_mnolrw1.d23
-rw-r--r--gas/testsuite/gas/csky/cskyv2_mnolrw1.s11
-rw-r--r--gas/testsuite/gas/csky/cskyv2_mnolrw2.d12
-rw-r--r--gas/testsuite/gas/csky/cskyv2_mnolrw2.s11
-rw-r--r--gas/testsuite/gas/csky/enhance_dsp.d217
-rw-r--r--gas/testsuite/gas/csky/enhance_dsp.s219
-rw-r--r--gas/testsuite/gas/csky/java.d12
-rw-r--r--gas/testsuite/gas/csky/java.s6
-rw-r--r--gas/testsuite/gas/csky/jbsr.d14
-rw-r--r--gas/testsuite/gas/csky/jbsr.s3
-rw-r--r--gas/testsuite/gas/csky/jbt.d16
-rw-r--r--gas/testsuite/gas/csky/jbt.s10
-rw-r--r--gas/testsuite/gas/csky/jbt_pic.d23
-rw-r--r--gas/testsuite/gas/csky/jbt_pic.s10
-rw-r--r--gas/testsuite/gas/csky/jmpi1.d16
-rw-r--r--gas/testsuite/gas/csky/jmpi1.s6
-rw-r--r--gas/testsuite/gas/csky/jmpi2.d14
-rw-r--r--gas/testsuite/gas/csky/jmpi2.s5
-rw-r--r--gas/testsuite/gas/csky/jmpi3.d9
-rw-r--r--gas/testsuite/gas/csky/jmpi3.s6
-rw-r--r--gas/testsuite/gas/csky/jmpiv2_1.d13
-rw-r--r--gas/testsuite/gas/csky/jmpiv2_1.s6
-rw-r--r--gas/testsuite/gas/csky/jmpiv2_2.d9
-rw-r--r--gas/testsuite/gas/csky/jmpiv2_2.s6
-rw-r--r--gas/testsuite/gas/csky/jsriv2_1.d13
-rw-r--r--gas/testsuite/gas/csky/jsriv2_1.s5
-rw-r--r--gas/testsuite/gas/csky/jsriv2_2.d14
-rw-r--r--gas/testsuite/gas/csky/jsriv2_2.s5
-rw-r--r--gas/testsuite/gas/csky/jsriv2_3.d9
-rw-r--r--gas/testsuite/gas/csky/jsriv2_3.s5
-rw-r--r--gas/testsuite/gas/csky/jsriv2_4.d9
-rw-r--r--gas/testsuite/gas/csky/jsriv2_4.s5
-rw-r--r--gas/testsuite/gas/csky/trust.d17
-rw-r--r--gas/testsuite/gas/csky/trust.s9
-rw-r--r--gas/testsuite/gas/csky/v1_float.d222
-rw-r--r--gas/testsuite/gas/csky/v1_float.s78
-rw-r--r--gas/testsuite/gas/csky/v2_float_part1.d54
-rw-r--r--gas/testsuite/gas/csky/v2_float_part1.s48
-rw-r--r--gas/testsuite/gas/csky/v2_float_part2.d20
-rw-r--r--gas/testsuite/gas/csky/v2_float_part2.s10
-rw-r--r--gas/testsuite/gas/csky/v2_tls_gd.d10
-rw-r--r--gas/testsuite/gas/csky/v2_tls_gd.s7
-rw-r--r--gas/testsuite/gas/csky/v2_tls_ie.d9
-rw-r--r--gas/testsuite/gas/csky/v2_tls_ie.s7
-rw-r--r--gas/testsuite/gas/csky/v2_tls_ld.d11
-rw-r--r--gas/testsuite/gas/csky/v2_tls_ld.s9
-rw-r--r--gas/testsuite/gas/csky/v2_tls_le.d9
-rw-r--r--gas/testsuite/gas/csky/v2_tls_le.s3
87 files changed, 10976 insertions, 1 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index f2a0c6a..3f5c4e5 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,24 @@
+2018-07-30 Andrew Jenner <andrew@codesourcery.com>
+
+ * Makefile.am (TARGET_CPU_CFILES): Add entry for C-SKY.
+ (TARGET_CPU_HFILES, TARGET_ENV_HFILES): Likewise.
+ * Makefile.in: Regenerated.
+ * config/tc-csky.c: New file.
+ * config/tc-csky.h: New file.
+ * config/te-csky_abiv1.h: New file.
+ * config/te-csky_abiv1_linux.h: New file.
+ * config/te-csky_abiv2.h: New file.
+ * config/te-csky_abiv2_linux.h: New file.
+ * configure.tgt: Add C-SKY.
+ * doc/Makefile.am (CPU_DOCS): Add entry for C-SKY.
+ * doc/Makefile.in: Regenerated.
+ * doc/all.texi: Set CSKY feature.
+ * doc/as.texi (Overview): Add C-SKY options.
+ (Machine Dependencies): Likewise.
+ * doc/c-csky.texi: New file.
+ * testsuite/gas/csky/*: New test cases.
+ * NEWS: Mention the support.
+
2018-07-29 John David Anglin <danglin@gcc.gnu.org>
* config/tc-hppa.c: Include "struc-symbol.h".
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 959e9e9..8f520d3 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -138,6 +138,7 @@ TARGET_CPU_CFILES = \
config/tc-cr16.c \
config/tc-cris.c \
config/tc-crx.c \
+ config/tc-csky.c \
config/tc-d10v.c \
config/tc-d30v.c \
config/tc-dlx.c \
@@ -212,6 +213,7 @@ TARGET_CPU_HFILES = \
config/tc-cr16.h \
config/tc-cris.h \
config/tc-crx.h \
+ config/tc-csky.h \
config/tc-d10v.h \
config/tc-d30v.h \
config/tc-dlx.h \
@@ -308,6 +310,10 @@ TARG_ENV_HFILES = \
config/te-armfbsdeabi.h \
config/te-armfbsdvfp.h \
config/te-armlinuxeabi.h \
+ config/te-csky_abiv1.h \
+ config/te-csky_abiv1_linux.h \
+ config/te-csky_abiv2.h \
+ config/te-csky_abiv2_linux.h \
config/te-freebsd.h \
config/te-generic.h \
config/te-gnu.h \
diff --git a/gas/Makefile.in b/gas/Makefile.in
index 42ae871..862f948 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -527,6 +527,7 @@ TARGET_CPU_CFILES = \
config/tc-cr16.c \
config/tc-cris.c \
config/tc-crx.c \
+ config/tc-csky.c \
config/tc-d10v.c \
config/tc-d30v.c \
config/tc-dlx.c \
@@ -601,6 +602,7 @@ TARGET_CPU_HFILES = \
config/tc-cr16.h \
config/tc-cris.h \
config/tc-crx.h \
+ config/tc-csky.h \
config/tc-d10v.h \
config/tc-d30v.h \
config/tc-dlx.h \
@@ -697,6 +699,10 @@ TARG_ENV_HFILES = \
config/te-armfbsdeabi.h \
config/te-armfbsdvfp.h \
config/te-armlinuxeabi.h \
+ config/te-csky_abiv1.h \
+ config/te-csky_abiv1_linux.h \
+ config/te-csky_abiv2.h \
+ config/te-csky_abiv2_linux.h \
config/te-freebsd.h \
config/te-generic.h \
config/te-gnu.h \
@@ -896,6 +902,8 @@ config/tc-cris.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
config/tc-crx.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
+config/tc-csky.$(OBJEXT): config/$(am__dirstamp) \
+ config/$(DEPDIR)/$(am__dirstamp)
config/tc-d10v.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
config/tc-d30v.$(OBJEXT): config/$(am__dirstamp) \
@@ -1146,6 +1154,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-cr16.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-cris.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-crx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-csky.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-d10v.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-d30v.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/tc-dlx.Po@am__quote@
diff --git a/gas/NEWS b/gas/NEWS
index c7d9332..1f441eb 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for the C-SKY processor series.
+
* Add support for the MIPS Loongson MultiMedia extensions Instructions (MMI)
ASE.
diff --git a/gas/config/tc-csky.c b/gas/config/tc-csky.c
new file mode 100644
index 0000000..bd0672f
--- /dev/null
+++ b/gas/config/tc-csky.c
@@ -0,0 +1,7299 @@
+/* tc-csky.c -- Assembler for C-SKY
+ Copyright (C) 1989-2018 Free Software Foundation, Inc.
+ Created by Lifang Xia (lifang_xia@c-sky.com)
+ Contributed by C-SKY Microsystems and Mentor Graphics.
+
+ 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "as.h"
+#include <limits.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "obstack.h"
+#include "libiberty.h"
+#include "struc-symbol.h"
+
+#ifdef OBJ_ELF
+#include "elf/csky.h"
+#include "dw2gencfi.h"
+#endif
+#include "tc-csky.h"
+#include "dwarf2dbg.h"
+
+#define BUILD_AS 1
+
+#define OPCODE_MAX_LEN 20
+#define HAS_SUB_OPERAND 0xfffffffful
+
+/* This value is just for lrw to distinguish "[]" label. */
+#define NEED_OUTPUT_LITERAL 1
+
+#define IS_EXTERNAL_SYM(sym, sec) (S_GET_SEGMENT (sym) != sec)
+#define IS_SUPPORT_OPCODE16(opcode) (opcode->isa_flag16 | isa_flag)
+#define IS_SUPPORT_OPCODE32(opcode) (opcode->isa_flag32 | isa_flag)
+
+
+#define KB * 1024
+#define MB KB * 1024
+#define GB MB * 1024
+
+/* Define DSP version flags. For different CPU, the version of DSP
+ instructions may be different. */
+#define CSKY_DSP_FLAG_V1 (1 << 0) /* Normal DSP instructions. */
+#define CSKY_DSP_FLAG_V2 (1 << 1) /* CK803S enhanced DSP. */
+
+/* Literal pool related macros. */
+/* 1024 - 1 entry - 2 byte rounding. */
+#define v1_SPANPANIC (998)
+#define v1_SPANCLOSE (900)
+#define v1_SPANEXIT (600)
+#define v2_SPANPANIC (1024 - 4)
+
+/* 1024 is flrw offset.
+ 24 is the biggest size for single instruction.
+ for lrw16 (3+7, 512 bytes). */
+#define v2_SPANCLOSE (512 - 24)
+
+/* For lrw16, 112 average size for a function. */
+#define v2_SPANEXIT (512 - 112)
+
+/* For lrw16 (3+7, 512 bytes). */
+#define v2_SPANCLOSE_ELRW (1016 - 24)
+
+/* For lrw16, 112 average size for a function. */
+#define v2_SPANEXIT_ELRW (1016 - 112)
+#define MAX_POOL_SIZE (1024 / 4)
+#define POOL_END_LABEL ".LE"
+#define POOL_START_LABEL ".LS"
+
+/* Used in v1_relax_table. */
+/* These are the two types of relaxable instruction. */
+#define COND_JUMP 1
+#define UNCD_JUMP 2
+#define COND_JUMP_PIC 3
+#define UNCD_JUMP_PIC 4
+
+#define UNDEF_DISP 0
+#define DISP12 1
+#define DISP32 2
+#define UNDEF_WORD_DISP 3
+
+#define C12_LEN 2
+/* Allow for align: bt/jmpi/.long + align. */
+#define C32_LEN 10
+/* Allow for align: bt/subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
+#define C32_LEN_PIC 24
+#define U12_LEN 2
+/* Allow for align: jmpi/.long + align. */
+#define U32_LEN 8
+/* Allow for align: subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
+#define U32_LEN_PIC 22
+
+#define C(what,length) (((what) << 2) + (length))
+#define UNCD_JUMP_S (do_pic ? UNCD_JUMP_PIC : UNCD_JUMP)
+#define COND_JUMP_S (do_pic ? COND_JUMP_PIC : COND_JUMP)
+#define U32_LEN_S (do_pic ? U32_LEN_PIC : U32_LEN)
+#define C32_LEN_S (do_pic ? C32_LEN_PIC : C32_LEN)
+
+/* Used in v2_relax_table. */
+#define COND_DISP10_LEN 2 /* bt/bf_16. */
+#define COND_DISP16_LEN 4 /* bt/bf_32. */
+
+#define SCOND_DISP10_LEN 2 /* bt/bf_16, for CK801 only. */
+#define SCOND_DISP16_LEN 6 /* !(bt/bf_16) + br_32. */
+
+#define UNCD_DISP10_LEN 2 /* br_16. */
+#define UNCD_DISP16_LEN 4 /* br_32. */
+#define UNCD_DISP26_LEN 4 /* br32_old. */
+
+#define JCOND_DISP10_LEN 2 /* bt/bf_16. */
+#define JCOND_DISP16_LEN 4 /* bt/bf_32. */
+#define JCOND_DISP32_LEN 12 /* !(bt/bf_16)/jmpi 32/.align 2/literal 4. */
+#define JCOND_DISP26_LEN 8 /* bt/bf_32/br_32 old. */
+
+#define JUNCD_DISP26_LEN 4 /* bt/bf_32 old. */
+#define JUNCD_DISP10_LEN 2 /* br_16. */
+#define JUNCD_DISP16_LEN 4 /* bt/bf_32. */
+#define JUNCD_DISP32_LEN 10 /* jmpi_32/.align 2/literal 4/ CHANGED!. */
+#define JCOMP_DISP26_LEN 8 /* bne_32/br_32 old. */
+
+#define JCOMP_DISP16_LEN 4 /* bne_32 old. */
+#define JCOMPZ_DISP16_LEN 4 /* bhlz_32. */
+#define JCOMPZ_DISP32_LEN 14 /* bsz_32/jmpi 32/.align 2/literal 4. */
+#define JCOMPZ_DISP26_LEN 8 /* bsz_32/br_32 old. */
+#define JCOMP_DISP32_LEN 14 /* be_32/jmpi_32/.align 2/literal old. */
+
+#define BSR_DISP10_LEN 2 /* bsr_16. */
+#define BSR_DISP26_LEN 4 /* bsr_32. */
+#define LRW_DISP7_LEN 2 /* lrw16. */
+#define LRW_DISP16_LEN 4 /* lrw32. */
+
+/* Declare worker functions. */
+bfd_boolean v1_work_lrw (void);
+bfd_boolean v1_work_jbsr (void);
+bfd_boolean v1_work_fpu_fo (void);
+bfd_boolean v1_work_fpu_fo_fc (void);
+bfd_boolean v1_work_fpu_write (void);
+bfd_boolean v1_work_fpu_read (void);
+bfd_boolean v1_work_fpu_writed (void);
+bfd_boolean v1_work_fpu_readd (void);
+bfd_boolean v2_work_istack (void);
+bfd_boolean v2_work_btsti (void);
+bfd_boolean v2_work_addi (void);
+bfd_boolean v2_work_subi (void);
+bfd_boolean v2_work_add_sub (void);
+bfd_boolean v2_work_rotlc (void);
+bfd_boolean v2_work_bgeni (void);
+bfd_boolean v2_work_not (void);
+bfd_boolean v2_work_jbtf (void);
+bfd_boolean v2_work_jbr (void);
+bfd_boolean v2_work_lrw (void);
+bfd_boolean v2_work_lrsrsw (void);
+bfd_boolean v2_work_jbsr (void);
+bfd_boolean v2_work_jsri (void);
+bfd_boolean v2_work_movih (void);
+bfd_boolean v2_work_ori (void);
+bfd_boolean float_work_fmovi (void);
+bfd_boolean dsp_work_bloop (void);
+
+/* csky-opc.h must be included after workers are declared. */
+#include "opcodes/csky-opc.h"
+#include "opcode/csky.h"
+
+enum
+{
+ RELAX_NONE = 0,
+ RELAX_OVERFLOW,
+
+ COND_DISP10 = 20, /* bt/bf_16. */
+ COND_DISP16, /* bt/bf_32. */
+
+ SCOND_DISP10, /* br_16 */
+ SCOND_DISP16, /* !(bt/bf_32) + br_32. */
+
+ UNCD_DISP10, /* br_16. */
+ UNCD_DISP16, /* br_32. */
+
+ JCOND_DISP10, /* bt/bf_16. */
+ JCOND_DISP16, /* bt/bf_32. */
+ JCOND_DISP32, /* !(bt/bf_32)/jmpi + literal. */
+
+ JUNCD_DISP10, /* br_16. */
+ JUNCD_DISP16, /* br_32. */
+ JUNCD_DISP32, /* jmpi + literal. */
+
+ JCOMPZ_DISP16, /* bez/bnez/bhz/blsz/blz/bhsz. */
+ JCOMPZ_DISP32, /* !(jbez/jbnez/jblsz/jblz/jbhsz) + jmpi + literal. */
+
+ BSR_DISP26, /* bsr_32. */
+
+ LRW_DISP7, /* lrw16. */
+ LRW2_DISP8, /* lrw16, -mno-bsr16,8 bit offset. */
+ LRW_DISP16, /* lrw32. */
+};
+
+unsigned int mach_flag = 0;
+unsigned int arch_flag = 0;
+unsigned int other_flag = 0;
+unsigned int isa_flag = 0;
+unsigned int dsp_flag = 0;
+
+typedef struct stack_size_entry
+{
+ struct stack_size_entry *next;
+ symbolS *function;
+ unsigned int stack_size;
+} stack_size_entry;
+
+struct csky_arch_info
+{
+ const char *name;
+ unsigned int arch_flag;
+ unsigned int bfd_mach_flag;
+};
+
+struct csky_cpu_info
+{
+ const char *name;
+ unsigned int mach_flag;
+ unsigned int isa_flag;
+};
+
+typedef enum
+{
+ INSN_OPCODE,
+ INSN_OPCODE16F,
+ INSN_OPCODE32F,
+} inst_flag;
+
+/* Macro information. */
+struct csky_macro_info
+{
+ const char *name;
+ /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
+ long oprnd_num;
+ int isa_flag;
+ /* Do the work. */
+ void (*handle_func)(void);
+};
+
+struct csky_insn_info
+{
+ /* Name of the opcode. */
+ char *name;
+ /* Output instruction. */
+ unsigned int inst;
+ /* Pointer for frag. */
+ char *output;
+ /* End of instruction. */
+ char *opcode_end;
+ /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
+ inst_flag flag_force;
+ /* Operand number. */
+ int number;
+ struct csky_opcode *opcode;
+ struct csky_macro_info *macro;
+ /* Insn size for check_literal. */
+ unsigned int isize;
+ /* Max size of insn for relax frag_var. */
+ unsigned int max;
+ /* Indicates which element is in csky_opcode_info op[] array. */
+ int opcode_idx;
+ /* The value of each operand in instruction when layout. */
+ int idx;
+ int val[MAX_OPRND_NUM];
+ struct relax_info
+ {
+ int max;
+ int var;
+ int subtype;
+ } relax;
+ /* The following are used for constant expressions. */
+ expressionS e1;
+ expressionS e2;
+};
+
+/* Literal pool data structures. */
+struct literal
+{
+ unsigned short refcnt;
+ unsigned char ispcrel;
+ unsigned char unused;
+ bfd_reloc_code_real_type r_type;
+ expressionS e;
+ struct tls_addend tls_addend;
+ unsigned char isdouble;
+ uint64_t dbnum;
+};
+
+static void csky_idly (void);
+static void csky_rolc (void);
+static void csky_sxtrb (void);
+static void csky_movtf (void);
+static void csky_addc64 (void);
+static void csky_subc64 (void);
+static void csky_or64 (void);
+static void csky_xor64 (void);
+static void csky_neg (void);
+static void csky_rsubi (void);
+static void csky_arith (void);
+static void csky_decne (void);
+static void csky_lrw (void);
+
+static enum bfd_reloc_code_real insn_reloc;
+
+/* Assembler operand parse errors use these identifiers. */
+
+enum error_number
+{
+ /* The following are errors. */
+ ERROR_CREG_ILLEGAL = 0,
+ ERROR_REG_OVER_RANGE,
+ ERROR_GREG_ILLEGAL,
+ ERROR_802J_REG_OVER_RANGE,
+ ERROR_REG_FORMAT,
+ ERROR_REG_LIST,
+ ERROR_IMM_ILLEGAL,
+ ERROR_IMM_OVERFLOW, /* 5 */
+ ERROR_IMM_POWER,
+ ERROR_JMPIX_OVER_RANGE,
+ ERROR_EXP_CREG,
+ ERROR_EXP_GREG,
+ ERROR_EXP_CONSTANT,
+ ERROR_EXP_EVEN_FREG,
+ ERROR_RELOC_ILLEGAL,
+ ERROR_MISSING_OPERAND, /* 10 */
+ ERROR_MISSING_COMMA,
+ ERROR_MISSING_LBRACKET,
+ ERROR_MISSING_RBRACKET,
+ ERROR_MISSING_LSQUARE_BRACKETS,
+ ERROR_MISSING_RSQUARE_BRACKETS, /* 15 */
+ ERROR_MISSING_LANGLE_BRACKETS,
+ ERROR_MISSING_RANGLE_BRACKETS,
+ ERROR_OFFSET_UNALIGNED,
+ ERROR_BAD_END,
+ ERROR_UNDEFINE,
+ ERROR_CPREG_ILLEGAL, /* 20 */
+ ERROR_OPCODE_PSRBIT,
+ ERROR_OPERANDS_ILLEGAL,
+ ERROR_OPERANDS_NUMBER,
+ ERROR_OPCODE_ILLEGAL,
+
+ /* The following are warnings. */
+ WARNING_OPTIONS,
+ WARNING_IDLY,
+
+ /* Error and warning end. */
+ ERROR_NONE,
+};
+
+/* Global error state. ARG1 and ARG2 are opaque data interpreted
+ as appropriate for the error code. */
+
+struct csky_error_state
+{
+ enum error_number err_num;
+ int opnum;
+ const void *arg1;
+ const void *arg2;
+} error_state;
+
+/* This macro is used to set error number and arg1 in the global state. */
+
+#define SET_ERROR_NUMBER(err, msg) \
+ do { \
+ if (error_state.err_num > err) \
+ { \
+ error_state.err_num = err; \
+ error_state.arg1 = (void *)msg; \
+ } \
+ } while (0)
+
+
+/* Map error identifiers onto a format string, which will use
+ arg1 and arg2 from the global error state. */
+struct csky_error_format_map
+{
+ enum error_number num;
+ const char *fmt;
+};
+
+static const struct csky_error_format_map err_formats[] =
+{
+ {ERROR_CREG_ILLEGAL, "Operand %d error: control register is illegal."},
+ {ERROR_REG_OVER_RANGE, "Operand %d error: r%d register is over range."},
+ {ERROR_GREG_ILLEGAL, "Operand %d error: general register is illegal."},
+ {ERROR_802J_REG_OVER_RANGE, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"},
+ {ERROR_REG_FORMAT, "Operand %d error: %s."},
+ {ERROR_REG_LIST, "Register list format is illegal."},
+ {ERROR_IMM_ILLEGAL, "Operand %d is not an immediate."},
+ {ERROR_IMM_OVERFLOW, "Operand %d immediate is overflow."},
+ {ERROR_IMM_POWER, "immediate %d is not a power of two"},
+ {ERROR_JMPIX_OVER_RANGE, "The second operand must be 16/24/32/40"},
+ {ERROR_EXP_CREG, "Operand %d error: control register is expected."},
+ {ERROR_EXP_GREG, "Operand %d error: general register is expected."},
+ {ERROR_EXP_CONSTANT, "Operand %d error: constant is expected."},
+ {ERROR_EXP_EVEN_FREG, "Operand %d error: even float register is expected."},
+ {ERROR_RELOC_ILLEGAL, "@%s reloc is not supported"},
+ {ERROR_MISSING_OPERAND, "Operand %d is missing."},
+ {ERROR_MISSING_COMMA, "Missing ','"},
+ {ERROR_MISSING_LBRACKET, "Missing '('"},
+ {ERROR_MISSING_RBRACKET, "Missing ')'"},
+ {ERROR_MISSING_LSQUARE_BRACKETS, "Missing '['"},
+ {ERROR_MISSING_RSQUARE_BRACKETS, "Missing ']'"},
+ {ERROR_MISSING_LANGLE_BRACKETS, "Missing '<'"},
+ {ERROR_MISSING_RANGLE_BRACKETS, "Missing '>'"},
+ {ERROR_OFFSET_UNALIGNED, "Operand %d is unaligned. It must be %d aligned!"},
+ {ERROR_BAD_END, "Operands mismatch, it has a bad end: %s"},
+ {ERROR_UNDEFINE, NULL},
+ {ERROR_CPREG_ILLEGAL, "Operand %d illegal, expect a cpreg(cpr0-cpr63)."},
+ {ERROR_OPCODE_PSRBIT, "The operands must be 'ie'/'ee'/'fe'."},
+ {ERROR_OPERANDS_ILLEGAL, "Operands mismatch: %s."},
+ {ERROR_OPERANDS_NUMBER, "Operands number mismatch, %d operands expected."},
+ {ERROR_OPCODE_ILLEGAL, "The instruction is not recognized."},
+ {WARNING_OPTIONS, "Option %s is not support in %s."},
+ {WARNING_IDLY, "idly %d is encoded to: idly 4 "},
+ {ERROR_NONE, "There is no error."},
+};
+
+static int do_pic = 0; /* for jbr/jbf/jbt relax jmpi reloc. */
+static int do_pff = -1; /* for insert two br ahead of literals. */
+static int do_force2bsr = -1; /* for jbsr->bsr. */
+static int do_jsri2bsr = 1; /* for jsri->bsr. */
+static int do_nolrw = 0; /* lrw to movih & ori, only for V2. */
+static int do_long_jump = -1; /* control if jbf,jbt,jbr relax to jmpi. */
+static int do_extend_lrw = -1; /* delete bsr16 in both two options,
+ add btesti16, lrw offset +1 in -melrw. */
+static int do_func_dump = 0; /* dump literals after every function. */
+static int do_br_dump = 1; /* work for -mabr/-mno-abr, control the literals dump. */
+static int do_intr_stack = -1; /* control interrupt stack module, 801&802&803
+ default on, 807&810, default off. */
+
+#ifdef INCLUDE_BRANCH_STUB
+static int do_use_branchstub = -1;
+#else
+static int do_use_branchstub = 0;
+#endif
+
+/* These are only used for options parsing. Values are bitmasks and are
+ OR'ed into the processor flag bits in md_begin. */
+static int do_opt_mmp = 0;
+static int do_opt_mcp = 0;
+static int do_opt_mcache = 0;
+static int do_opt_msecurity = 0;
+static int do_opt_mhard_float = 0;
+static int do_opt_mtrust = 0;
+static int do_opt_mdsp = 0;
+static int do_opt_medsp = 0;
+static int do_opt_mvdsp = 0;
+
+const relax_typeS *md_relax_table = NULL;
+struct literal *literal_insn_offset;
+static struct literal litpool[MAX_POOL_SIZE];
+static unsigned poolsize = 0;
+static unsigned poolnumber = 0;
+static unsigned long poolspan = 0;
+static unsigned int SPANPANIC;
+static unsigned int SPANCLOSE;
+static unsigned int SPANEXIT;
+
+static stack_size_entry *all_stack_size_data = NULL;
+static stack_size_entry **last_stack_size_data = &all_stack_size_data;
+
+/* Control by ".no_literal_dump N"
+ * 1 : don't dump literal pool between insn1 and insnN+1
+ * 0 : do nothing. */
+static int do_noliteraldump = 0;
+
+/* Label for current pool. */
+static symbolS * poolsym;
+static char poolname[8];
+
+static bfd_boolean mov_r1_before;
+static bfd_boolean mov_r1_after;
+
+const relax_typeS csky_relax_table [] =
+{
+ /* C-SKY V1 relax table. */
+ {0, 0, 0, 0}, /* RELAX_NONE */
+ {0, 0, 0, 0}, /* RELAX_OVERFLOW */
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+
+ /* COND_JUMP */
+ { 0, 0, 0, 0 }, /* UNDEF_DISP */
+ { 2048, -2046, C12_LEN, C (COND_JUMP, DISP32) }, /* DISP12 */
+ { 0, 0, C32_LEN, 0 }, /* DISP32 */
+ { 0, 0, C32_LEN, 0 }, /* UNDEF_WORD_DISP */
+
+ /* UNCD_JUMP */
+ { 0, 0, 0, 0 }, /* UNDEF_DISP */
+ { 2048, -2046, U12_LEN, C (UNCD_JUMP, DISP32) }, /* DISP12 */
+ { 0, 0, U32_LEN, 0 }, /* DISP32 */
+ { 0, 0, U32_LEN, 0 }, /* UNDEF_WORD_DISP */
+
+ /* COND_JUMP_PIC */
+ { 0, 0, 0, 0 }, /* UNDEF_DISP */
+ { 2048, -2046, C12_LEN, C (COND_JUMP_PIC, DISP32) }, /* DISP12 */
+ { 0, 0, C32_LEN_PIC, 0 }, /* DISP32 */
+ { 0, 0, C32_LEN_PIC, 0 }, /* UNDEF_WORD_DISP */
+
+ /* UNCD_JUMP_PIC */
+ { 0, 0, 0, 0 }, /* UNDEF_DISP */
+ { 2048, -2046, U12_LEN, C (UNCD_JUMP_PIC, DISP32) }, /* DISP12 */
+ { 0, 0, U32_LEN_PIC, 0 }, /* DISP32 */
+ { 0, 0, U32_LEN_PIC, 0 }, /* UNDEF_WORD_DISP */
+
+ /* C-SKY V2 relax table. */
+ /* forward backward length more */
+ { 1 KB - 2, -1 KB, COND_DISP10_LEN, COND_DISP16 }, /* COND_DISP10 */
+ { 64 KB - 2, -64 KB, COND_DISP16_LEN, RELAX_OVERFLOW }, /* COND_DISP16 */
+
+ { 1 KB - 2, -1 KB, SCOND_DISP10_LEN, SCOND_DISP16 }, /* SCOND_DISP10 */
+ { 64 KB - 2, -64 KB, SCOND_DISP16_LEN, RELAX_OVERFLOW }, /* SCOND_DISP16 */
+
+ { 1 KB - 2, -1 KB, UNCD_DISP10_LEN, UNCD_DISP16 }, /* UNCD_DISP10 */
+ { 64 KB - 2, -64 KB, UNCD_DISP16_LEN, RELAX_OVERFLOW }, /* UNCD_DISP16 */
+
+ { 1 KB - 2, -1 KB, JCOND_DISP10_LEN, JCOND_DISP16 }, /* JCOND_DISP10 */
+ { 64 KB - 2, -64 KB, JCOND_DISP16_LEN, JCOND_DISP32 }, /* JCOND_DISP16 */
+ { 0, 0, JCOND_DISP32_LEN, RELAX_NONE }, /* JCOND_DISP32 */
+
+ { 1 KB - 2, -1 KB, JUNCD_DISP10_LEN, JUNCD_DISP16 }, /* JUNCD_DISP10 */
+ { 64 KB - 2, -64 KB, JUNCD_DISP16_LEN, JUNCD_DISP32 }, /* JUNCD_DISP16 */
+ { 0, 0, JUNCD_DISP32_LEN, RELAX_NONE }, /* JUNCD_DISP32 */
+
+ { 64 KB - 2, -64 KB, JCOMPZ_DISP16_LEN, JCOMPZ_DISP32 }, /* JCOMPZ_DISP16 */
+ { 0, 0, JCOMPZ_DISP32_LEN, RELAX_NONE }, /* JCOMPZ_DISP32 */
+
+ { 64 MB - 2, -64 MB, BSR_DISP26_LEN, RELAX_OVERFLOW }, /* BSR_DISP26 */
+
+ { 508, 0, LRW_DISP7_LEN, LRW_DISP16 }, /* LRW_DISP7 */
+ { 1016, 0, LRW_DISP7_LEN, LRW_DISP16 }, /* LRW2_DISP8 */
+ { 64 KB, 0, LRW_DISP16_LEN, RELAX_OVERFLOW }, /* LRW_DISP16 */
+
+};
+
+static void csky_write_insn (char *ptr, valueT use, int nbytes);
+void md_number_to_chars (char * buf, valueT val, int n);
+long md_pcrel_from_section (fixS * fixP, segT seg);
+
+/* C-SKY architecture table. */
+const struct csky_arch_info csky_archs[] =
+{
+ {"ck510", CSKY_ARCH_510, bfd_mach_ck510},
+ {"ck610", CSKY_ARCH_610, bfd_mach_ck610},
+ {"ck801", CSKY_ARCH_801, bfd_mach_ck801},
+ {"ck802", CSKY_ARCH_802, bfd_mach_ck802},
+ {"ck803", CSKY_ARCH_803, bfd_mach_ck803},
+#define CSKY_ARCH_807_BASE CSKY_ARCH_807 | CSKY_ARCH_DSP
+#define CSKY_ARCH_810_BASE CSKY_ARCH_810 | CSKY_ARCH_DSP
+ {"ck807", CSKY_ARCH_807_BASE, bfd_mach_ck807},
+ {"ck810", CSKY_ARCH_810_BASE, bfd_mach_ck810},
+ {NULL, 0, 0}
+};
+
+/* C-SKY cpus table. */
+const struct csky_cpu_info csky_cpus[] =
+{
+ /* CK510 series. */
+#define CSKYV1_ISA_DSP CSKY_ISA_DSP | CSKY_ISA_MAC_DSP
+ {"ck510", CSKY_ARCH_510, CSKYV1_ISA_E1},
+ {"ck510e", CSKY_ARCH_510 | CSKY_ARCH_DSP, CSKYV1_ISA_E1 | CSKYV1_ISA_DSP},
+ {"ck520", CSKY_ARCH_510 | CSKY_ARCH_MAC, CSKYV1_ISA_E1 | CSKY_ISA_MAC | CSKY_ISA_MAC_DSP},
+
+#define CSKY_ISA_610 CSKYV1_ISA_E1 | CSKY_ISA_CP
+ /* CK610 series. */
+ {"ck610", CSKY_ARCH_610, CSKY_ISA_610},
+ {"ck610e", CSKY_ARCH_610 | CSKY_ARCH_DSP, CSKY_ISA_610 | CSKYV1_ISA_DSP},
+ {"ck610f", CSKY_ARCH_610 | CSKY_ARCH_FLOAT, CSKY_ISA_610 | CSKY_ISA_FLOAT_E1},
+ {"ck610ef", CSKY_ARCH_610 | CSKY_ARCH_FLOAT | CSKY_ARCH_DSP, CSKY_ISA_610 | CSKY_ISA_FLOAT_E1 | CSKYV1_ISA_DSP},
+ {"ck610fe", CSKY_ARCH_610 | CSKY_ARCH_FLOAT | CSKY_ARCH_DSP, CSKY_ISA_610 | CSKY_ISA_FLOAT_E1 | CSKYV1_ISA_DSP},
+ {"ck620", CSKY_ARCH_610 | CSKY_ARCH_MAC, CSKY_ISA_610 | CSKY_ISA_MAC | CSKY_ISA_MAC_DSP},
+
+ /* CK801 series. */
+#define CSKY_ISA_801 CSKYV2_ISA_E1
+#define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2)
+ {"ck801", CSKY_ARCH_801, CSKY_ISA_801},
+ {"ck801t", CSKY_ARCH_801, CSKY_ISA_801 | CSKY_ISA_TRUST},
+
+ /* CK802 series. */
+#define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
+ {"ck802", CSKY_ARCH_802, CSKY_ISA_802},
+ {"ck802j", CSKY_ARCH_802 | CSKY_ARCH_JAVA, CSKY_ISA_802 | CSKY_ISA_JAVA},
+ {"ck802t", CSKY_ARCH_802, CSKY_ISA_802 | CSKY_ISA_TRUST},
+
+ /* CK803 series. */
+#define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
+#define CSKY_ISA_803R1 (CSKY_ISA_803 | CSKYV2_ISA_3E3R1)
+#define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
+ {"ck803", CSKY_ARCH_803, CSKY_ISA_803 },
+ {"ck803h", CSKY_ARCH_803, CSKY_ISA_803 },
+ {"ck803t", CSKY_ARCH_803, CSKY_ISA_803 | CSKY_ISA_TRUST},
+ {"ck803ht", CSKY_ARCH_803, CSKY_ISA_803 | CSKY_ISA_TRUST},
+ {"ck803f", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803 | CSKY_ISA_FLOAT_803},
+ {"ck803fh", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803 | CSKY_ISA_FLOAT_803},
+ {"ck803e", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803 | CSKYV2_ISA_DSP},
+ {"ck803eh", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803 | CSKYV2_ISA_DSP},
+ {"ck803et", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803 | CSKYV2_ISA_DSP | CSKY_ISA_TRUST},
+ {"ck803eht", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803 | CSKYV2_ISA_DSP | CSKY_ISA_TRUST},
+ {"ck803ef", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_803},
+ {"ck803efh", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_803},
+ {"ck803ft", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803 | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+ {"ck803eft", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+ {"ck803efht", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+ {"ck803r1", CSKY_ARCH_803, CSKY_ISA_803R1 },
+ {"ck803hr1", CSKY_ARCH_803, CSKY_ISA_803R1 },
+ {"ck803tr1", CSKY_ARCH_803, CSKY_ISA_803R1 | CSKY_ISA_TRUST},
+ {"ck803htr1", CSKY_ARCH_803, CSKY_ISA_803R1 | CSKY_ISA_TRUST},
+ {"ck803fr1", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_FLOAT_803},
+ {"ck803fhr1", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_FLOAT_803},
+ {"ck803er1", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE},
+ {"ck803ehr1", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE},
+ {"ck803etr1", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_TRUST},
+ {"ck803ehtr1", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_TRUST},
+ {"ck803efr1", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803},
+ {"ck803efhr1", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803},
+ {"ck803ftr1", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+ {"ck803eftr1", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+ {"ck803ehftr1", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+
+ {"ck803s", CSKY_ARCH_803, CSKY_ISA_803R1 },
+ {"ck803se", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R1 | CSKYV2_ISA_DSP},
+ {"ck803sj", CSKY_ARCH_803 | CSKY_ARCH_JAVA, CSKY_ISA_803R1 | CSKY_ISA_JAVA},
+ {"ck803sf", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_FLOAT_803},
+ {"ck803sef", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_803},
+ {"ck803st", CSKY_ARCH_803, CSKY_ISA_803R1 | CSKY_ISA_TRUST},
+
+ /* CK807 series. */
+#define CSKY_ISA_807 (CSKY_ISA_803 | CSKYV2_ISA_3E7 | CSKY_ISA_DSP | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE)
+#define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
+ {"ck807e", CSKY_ARCH_807_BASE, CSKY_ISA_807 | CSKYV2_ISA_DSP},
+ {"ck807ef", CSKY_ARCH_807_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_807 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_807},
+ {"ck807", CSKY_ARCH_807_BASE, CSKY_ISA_807 | CSKYV2_ISA_DSP},
+ {"ck807f", CSKY_ARCH_807_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_807 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_807},
+
+ /* CK810 series. */
+#define CSKY_ISA_810 (CSKY_ISA_807 | CSKYV2_ISA_7E10)
+#define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
+ {"ck810e", CSKY_ARCH_810_BASE, CSKY_ISA_810 | CSKYV2_ISA_DSP},
+ {"ck810et", CSKY_ARCH_810_BASE, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_TRUST},
+ {"ck810ef", CSKY_ARCH_810_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_810},
+ {"ck810eft", CSKY_ARCH_810_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_810 | CSKY_ISA_TRUST},
+ {"ck810", CSKY_ARCH_810_BASE, CSKY_ISA_810 | CSKYV2_ISA_DSP},
+ {"ck810v", CSKY_ARCH_810_BASE, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_VDSP},
+ {"ck810f", CSKY_ARCH_810_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_FLOAT_810},
+ {"ck810t", CSKY_ARCH_810_BASE, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_TRUST},
+ {"ck810tv", CSKY_ARCH_810_BASE, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_TRUST},
+ {"ck810ft", CSKY_ARCH_810_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_VDSP | CSKY_ISA_FLOAT_810 | CSKY_ISA_TRUST},
+ {"ck810ftv", CSKY_ARCH_810_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_VDSP | CSKY_ISA_FLOAT_810 | CSKY_ISA_TRUST},
+
+ {NULL, 0, 0}
+};
+
+int md_short_jump_size = 2;
+int md_long_jump_size = 4;
+
+/* 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 comments like this one will always work. */
+const char line_comment_chars[] = "#";
+
+const char line_separator_chars[] = ";";
+
+/* Chars that can be used to separate mant
+ from exp in floating point numbers. */
+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[] = "rRsSfFdDxXeEpP";
+
+const char *md_shortopts = "";
+
+struct option md_longopts[] = {
+#define OPTION_MARCH (OPTION_MD_BASE + 0)
+ {"march", required_argument, NULL, OPTION_MARCH},
+#define OPTION_MCPU (OPTION_MD_BASE + 1)
+ {"mcpu", required_argument, NULL, OPTION_MCPU},
+
+ /* Remaining options just set boolean flags. */
+ {"EL", no_argument, &target_big_endian, 0},
+ {"mlittle-endian", no_argument, &target_big_endian, 0},
+ {"EB", no_argument, &target_big_endian, 1},
+ {"mbig-endian", no_argument, &target_big_endian, 1},
+ {"fpic", no_argument, &do_pic, 1},
+ {"pic", no_argument, &do_pic, 1},
+ {"mljump", no_argument, &do_long_jump, 1},
+ {"mno-ljump", no_argument, &do_long_jump, 0},
+ {"force2bsr", no_argument, &do_force2bsr, 1},
+ {"mforce2bsr", no_argument, &do_force2bsr, 1},
+ {"no-force2bsr", no_argument, &do_force2bsr, 0},
+ {"mno-force2bsr", no_argument, &do_force2bsr, 0},
+ {"jsri2bsr", no_argument, &do_jsri2bsr, 1},
+ {"mjsri2bsr", no_argument, &do_jsri2bsr, 1},
+ {"no-jsri2bsr", no_argument, &do_jsri2bsr, 0},
+ {"mno-jsri2bsr", no_argument, &do_jsri2bsr, 0},
+ {"mnolrw", no_argument, &do_nolrw, 1},
+ {"mno-lrw", no_argument, &do_nolrw, 1},
+ {"melrw", no_argument, &do_extend_lrw, 1},
+ {"mno-elrw", no_argument, &do_extend_lrw, 0},
+ {"mlaf", no_argument, &do_func_dump, 1},
+ {"mliterals-after-func", no_argument, &do_func_dump, 1},
+ {"mno-laf", no_argument, &do_func_dump, 0},
+ {"mno-literals-after-func", no_argument, &do_func_dump, 0},
+ {"mlabr", no_argument, &do_br_dump, 1},
+ {"mliterals-after-br", no_argument, &do_br_dump, 1},
+ {"mno-labr", no_argument, &do_br_dump, 0},
+ {"mnoliterals-after-br", no_argument, &do_br_dump, 0},
+ {"mistack", no_argument, &do_intr_stack, 1},
+ {"mno-istack", no_argument, &do_intr_stack, 0},
+#ifdef INCLUDE_BRANCH_STUB
+ {"mbranch-stub", no_argument, &do_use_branchstub, 1},
+ {"mno-branch-stub", no_argument, &do_use_branchstub, 0},
+#endif
+ {"mhard-float", no_argument, &do_opt_mhard_float, CSKY_ARCH_FLOAT},
+ {"mmp", no_argument, &do_opt_mmp, CSKY_ARCH_MP},
+ {"mcp", no_argument, &do_opt_mcp, CSKY_ARCH_CP},
+ {"mcache", no_argument, &do_opt_mcache, CSKY_ARCH_CACHE},
+ {"msecurity", no_argument, &do_opt_msecurity, CSKY_ARCH_MAC},
+ {"mtrust", no_argument, &do_opt_mtrust, CSKY_ISA_TRUST},
+ {"mdsp", no_argument, &do_opt_mdsp, CSKY_DSP_FLAG_V1},
+ {"medsp", no_argument, &do_opt_medsp, CSKY_DSP_FLAG_V2},
+ {"mvdsp", no_argument, &do_opt_mvdsp, CSKY_ISA_VDSP},
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+static struct csky_insn_info csky_insn;
+
+static struct hash_control *csky_opcodes_hash;
+static struct hash_control *csky_macros_hash;
+
+static struct csky_macro_info v1_macros_table[] =
+{
+ {"idly", 1, CSKYV1_ISA_E1, csky_idly},
+ {"rolc", 2, CSKYV1_ISA_E1, csky_rolc},
+ {"rotlc", 2, CSKYV1_ISA_E1, csky_rolc},
+ {"sxtrb0", 2, CSKYV1_ISA_E1, csky_sxtrb},
+ {"sxtrb1", 2, CSKYV1_ISA_E1, csky_sxtrb},
+ {"sxtrb2", 2, CSKYV1_ISA_E1, csky_sxtrb},
+ {"movtf", 3, CSKYV1_ISA_E1, csky_movtf},
+ {"addc64", 3, CSKYV1_ISA_E1, csky_addc64},
+ {"subc64", 3, CSKYV1_ISA_E1, csky_subc64},
+ {"or64", 3, CSKYV1_ISA_E1, csky_or64},
+ {"xor64", 3, CSKYV1_ISA_E1, csky_xor64},
+ {NULL,0,0,0}
+};
+
+static struct csky_macro_info v2_macros_table[] =
+{
+ {"neg", 1, CSKYV2_ISA_E1, csky_neg},
+ {"rsubi", 2, CSKYV2_ISA_1E2, csky_rsubi},
+ {"incf", 1, CSKYV2_ISA_1E2, csky_arith},
+ {"inct", 1, CSKYV2_ISA_1E2, csky_arith},
+ {"decf", 1, CSKYV2_ISA_2E3, csky_arith},
+ {"decgt", 1, CSKYV2_ISA_2E3, csky_arith},
+ {"declt", 1, CSKYV2_ISA_2E3, csky_arith},
+ {"decne", 1, CSKYV2_ISA_1E2, csky_decne},
+ {"dect", 1, CSKYV2_ISA_1E2, csky_arith},
+ {"lslc", 1, CSKYV2_ISA_1E2, csky_arith},
+ {"lsrc", 1, CSKYV2_ISA_1E2, csky_arith},
+ {"xsr", 1, CSKYV2_ISA_1E2, csky_arith},
+ {NULL,0,0,0}
+};
+
+/* For option -mnolrw, replace lrw by movih & ori. */
+static struct csky_macro_info v2_lrw_macro_opcode =
+ {"lrw", 2, CSKYV2_ISA_1E2, csky_lrw};
+
+/* This function is used to show errors or warnings. */
+
+static void
+csky_show_error (enum error_number err, int idx, void *arg1, void *arg2)
+{
+ if (err == ERROR_NONE)
+ return;
+
+ switch (err)
+ {
+ case ERROR_REG_LIST:
+ case ERROR_OPCODE_PSRBIT:
+ case ERROR_OPCODE_ILLEGAL:
+ case ERROR_JMPIX_OVER_RANGE:
+ case ERROR_MISSING_COMMA:
+ case ERROR_MISSING_LBRACKET:
+ case ERROR_MISSING_RBRACKET:
+ case ERROR_MISSING_LSQUARE_BRACKETS:
+ case ERROR_MISSING_RSQUARE_BRACKETS:
+ case ERROR_MISSING_LANGLE_BRACKETS:
+ case ERROR_MISSING_RANGLE_BRACKETS:
+ /* Add NULL to fix warnings. */
+ as_bad (_(err_formats[err].fmt), NULL);
+ break;
+ case ERROR_CREG_ILLEGAL:
+ case ERROR_GREG_ILLEGAL:
+ case ERROR_IMM_ILLEGAL:
+ case ERROR_IMM_OVERFLOW:
+ case ERROR_EXP_CREG:
+ case ERROR_EXP_GREG:
+ case ERROR_EXP_CONSTANT:
+ case ERROR_EXP_EVEN_FREG:
+ case ERROR_MISSING_OPERAND:
+ case ERROR_CPREG_ILLEGAL:
+ as_bad (_(err_formats[err].fmt), idx);
+ break;
+ case ERROR_OPERANDS_NUMBER:
+ case ERROR_IMM_POWER:
+ as_bad (_(err_formats[err].fmt), (long)arg1);
+ break;
+
+ case ERROR_OFFSET_UNALIGNED:
+ as_bad (_(err_formats[err].fmt), idx, (long)arg1);
+ break;
+ case ERROR_RELOC_ILLEGAL:
+ case ERROR_BAD_END:
+ case ERROR_OPERANDS_ILLEGAL:
+ as_bad (_(err_formats[err].fmt), (char *)arg1);
+ break;
+ case ERROR_REG_OVER_RANGE:
+ as_bad (_(err_formats[err].fmt), idx, (long) arg1);
+ break;
+ case ERROR_802J_REG_OVER_RANGE:
+ case ERROR_REG_FORMAT:
+ as_bad (_(err_formats[err].fmt), idx, (char *)arg1);
+ break;
+ case ERROR_UNDEFINE:
+ /* Add NULL to fix warnings. */
+ as_bad ((char *)arg1, NULL);
+ break;
+ case WARNING_IDLY:
+ as_warn (_(err_formats[err].fmt), (long)arg1);
+ break;
+ case WARNING_OPTIONS:
+ as_warn (_(err_formats[err].fmt), (char *)arg1, (char *)arg2);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Handle errors in branch relaxation. */
+
+static void
+csky_branch_report_error (const char* file, unsigned int line,
+ symbolS* sym, offsetT val)
+{
+ as_bad_where (file ? file : _("unknown"),
+ line,
+ _("pcrel offset for branch to %s too far (0x%lx)"),
+ sym ? S_GET_NAME (sym) : _("<unknown>"),
+ (long) val);
+}
+
+/* Set appropriate flags for the cpu matching STR. */
+
+static void
+parse_cpu (const char *str)
+{
+ int i = 0;
+
+ for (; csky_cpus[i].name != NULL; i++)
+ if (strcasecmp (str, csky_cpus[i].name) == 0)
+ {
+ mach_flag |= csky_cpus[i].mach_flag;
+ isa_flag = csky_cpus[i].isa_flag;
+ other_flag |= (csky_cpus[i].mach_flag & ~CSKY_ARCH_MASK);
+ return;
+ }
+ as_bad (_("unknown cpu `%s'"), str);
+}
+
+/* Set appropriate flags for the arch matching STR. */
+
+static void
+parse_arch (const char *str)
+{
+ int i = 0;
+ for (; csky_archs[i].name != NULL; i++)
+ if (strcasecmp (str, csky_archs[i].name) == 0)
+ {
+ arch_flag |= csky_archs[i].arch_flag;
+ return;
+ }
+ as_bad (_("unknown architecture `%s'"), str);
+}
+
+
+#ifdef OBJ_ELF
+/* Implement the TARGET_FORMAT macro. */
+
+const char *
+elf32_csky_target_format (void)
+{
+ return (target_big_endian
+ ? "elf32-csky-big"
+ : "elf32-csky-little");
+}
+#endif
+
+/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
+ for use in the a.out file, and stores them in the array pointed to by buf.
+ This knows about the endian-ness of the target machine and does
+ THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
+ 2 (short) and 4 (long) Floating numbers are put out as a series of
+ LITTLENUMS (shorts, here at least). */
+
+void
+md_number_to_chars (char * buf, valueT val, int n)
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Get a log2(val). */
+
+static int
+csky_log_2 (unsigned int val)
+{
+ int log = -1;
+ if ((val & (val - 1)) == 0)
+ for (; val; val >>= 1)
+ log ++;
+ else
+ csky_show_error (ERROR_IMM_POWER, 0, (void *)(long)val, NULL);
+ return log;
+}
+
+/* Output one instruction to the buffer at PTR. */
+
+static void
+csky_write_insn (char *ptr, valueT use, int nbytes)
+{
+ if (nbytes == 2)
+ md_number_to_chars (ptr, use, nbytes);
+ else /* 32-bit instruction. */
+ {
+ /* Significant figures are in low bits. */
+ md_number_to_chars (ptr, use >> 16, 2);
+ md_number_to_chars (ptr + 2, use & 0xFFFF, 2);
+ }
+}
+
+/* Read an NBYTES instruction from the buffer at PTR. NBYTES should
+ be either 2 or 4. This function is used in branch relaxation. */
+
+static valueT
+csky_read_insn (char *ptr, int nbytes)
+{
+ unsigned char *uptr = (unsigned char *)ptr;
+ valueT v = 0;
+ int lo, hi; /* hi/lo byte index in binary stream. */
+
+ if (target_big_endian)
+ {
+ hi = 0;
+ lo = 1;
+ }
+ else
+ {
+ hi = 1;
+ lo = 0;
+ }
+ v = uptr[lo] | (uptr[hi] << 8);
+ if (nbytes == 4)
+ {
+ v <<= 16;
+ v |= uptr[lo + 2] | (uptr[hi + 2] << 8);
+ }
+ return v;
+}
+
+/* Construct a label name into S from the 3-character prefix P and
+ number N formatted as a 4-digit hex number. */
+
+static void
+make_internal_label (char *s, const char *p, int n)
+{
+ static const char hex[] = "0123456789ABCDEF";
+
+ s[0] = p[0];
+ s[1] = p[1];
+ s[2] = p[2];
+ s[3] = hex[(n >> 12) & 0xF];
+ s[4] = hex[(n >> 8) & 0xF];
+ s[5] = hex[(n >> 4) & 0xF];
+ s[6] = hex[(n) & 0xF];
+ s[7] = 0;
+}
+
+/* md_operand is a no-op on C-SKY; we do everything elsewhere. */
+
+void
+md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
+{
+ return;
+}
+
+/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
+ Otherwise we have no need to default values of symbols. */
+
+symbolS *
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
+{
+#ifdef OBJ_ELF
+ /* TODO: */
+#endif
+ return NULL;
+}
+
+/* Use IEEE format for floating-point constants. */
+
+const char *
+md_atof (int type, char *litP, int *sizeP)
+{
+ return ieee_md_atof (type, litP, sizeP, target_big_endian);
+}
+
+/* Print option help to FP. */
+
+void
+md_show_usage (FILE *fp)
+{
+ int i, n;
+ const int margin = 48;
+
+ fprintf (fp, _("C-SKY assembler options:\n"));
+
+ fprintf (fp, _("\
+ -march=ARCH select architecture ARCH:"));
+ for (i = 0, n = margin; csky_archs[i].name != NULL; i++)
+ {
+ int l = strlen (csky_archs[i].name);
+ if (n + l >= margin)
+ {
+ fprintf (fp, "\n\t\t\t\t");
+ n = l;
+ }
+ else
+ {
+ fprintf (fp, " ");
+ n += l + 1;
+ }
+ fprintf (fp, "%s", csky_archs[i].name);
+ }
+ fprintf (fp, "\n");
+
+ fprintf (fp, _("\
+ -mcpu=CPU select processor CPU:"));
+ for (i = 0, n = margin; csky_cpus[i].name != NULL; i++)
+ {
+ int l = strlen (csky_cpus[i].name);
+ if (n + l >= margin)
+ {
+ fprintf (fp, "\n\t\t\t\t");
+ n = l;
+ }
+ else
+ {
+ fprintf (fp, " ");
+ n += l + 1;
+ }
+ fprintf (fp, "%s", csky_cpus[i].name);
+ }
+ fprintf (fp, "\n");
+
+ fprintf (fp, _("\
+ -EL -mlittle-endian generate little-endian output\n"));
+ fprintf (fp, _("\
+ -EB -mbig-endian generate big-endian output\n"));
+ fprintf (fp, _("\
+ -fpic -pic generate position-independent code\n"));
+
+ fprintf (fp, _("\
+ -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
+ fprintf (fp, _("\
+ -mno-ljump\n"));
+
+#ifdef INCLUDE_BRANCH_STUB
+ fprintf (fp, _("\
+ -mbranch-stub enable branch stubs for PC-relative calls\n"));
+ fprintf (fp, _("\
+ -mno-branch-stub\n"));
+#endif
+
+ fprintf (fp, _("\
+ -force2bsr -mforce2bsr transform jbsr to bsr\n"));
+ fprintf (fp, _("\
+ -no-force2bsr -mno-force2bsr\n"));
+ fprintf (fp, _("\
+ -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
+ fprintf (fp, _("\
+ -no-jsri2bsr -mno-jsri2bsr\n"));
+
+ fprintf (fp, _("\
+ -mnolrw -mno-lrw implement lrw as movih + ori\n"));
+ fprintf (fp, _("\
+ -melrw enable extended lrw (CK800 only)\n"));
+ fprintf (fp, _("\
+ -mno-elrw\n"));
+
+ fprintf (fp, _("\
+ -mlaf -mliterals-after-func emit literals after each function\n"));
+ fprintf (fp, _("\
+ -mno-laf -mno-literals-after-func\n"));
+ fprintf (fp, _("\
+ -mlabr -mliterals-after-br emit literals after branch instructions\n"));
+ fprintf (fp, _("\
+ -mno-labr -mnoliterals-after-br\n"));
+
+ fprintf (fp, _("\
+ -mistack enable interrupt stack instructions\n"));
+ fprintf (fp, _("\
+ -mno-istack\n"));
+
+ fprintf (fp, _("\
+ -mhard-float enable hard float instructions\n"));
+ fprintf (fp, _("\
+ -mmp enable multiprocessor instructions\n"));
+ fprintf (fp, _("\
+ -mcp enable coprocessor instructions\n"));
+ fprintf (fp, _("\
+ -mcache enable cache prefetch instruction\n"));
+ fprintf (fp, _("\
+ -msecurity enable security instructions\n"));
+ fprintf (fp, _("\
+ -mtrust enable trust instructions\n"));
+ fprintf (fp, _("\
+ -mdsp enable DSP instructions\n"));
+ fprintf (fp, _("\
+ -medsp enable enhanced DSP instructions\n"));
+ fprintf (fp, _("\
+ -mvdsp enable vector DSP instructions\n"));
+}
+
+/* Target-specific initialization and option handling. */
+
+void
+md_begin (void)
+{
+ unsigned int bfd_mach_flag = 0;
+ struct csky_opcode const *opcode;
+ struct csky_macro_info const *macro;
+ struct csky_arch_info const *p_arch;
+ struct csky_cpu_info const *p_cpu;
+ unsigned int flags = (other_flag | do_opt_mmp | do_opt_mcp | do_opt_mcache
+ | do_opt_msecurity | do_opt_mhard_float);
+ dsp_flag |= do_opt_mdsp | do_opt_medsp;
+ isa_flag |= do_opt_mtrust | do_opt_mvdsp;
+
+ if (dsp_flag)
+ flags |= CSKY_ARCH_DSP;
+
+ if (mach_flag != 0)
+ {
+ if ((mach_flag & CSKY_ARCH_MASK) != arch_flag && arch_flag != 0)
+ as_warn (_("-mcpu conflict with -march option, using -mcpu"));
+ if ((mach_flag & ~CSKY_ARCH_MASK) != flags && flags != 0)
+ as_warn (_("-mcpu conflict with other model parameters, using -mcpu"));
+ }
+ else if (arch_flag != 0)
+ mach_flag |= arch_flag | flags;
+ else
+ {
+#ifdef TARGET_WITH_CPU
+ int i = 0;
+ for (; csky_cpus[i].name != NULL; i++)
+ {
+ if (strcmp (TARGET_WITH_CPU, csky_cpus[i].name) == 0)
+ {
+ mach_flag |= csky_cpus[i].mach_flag;
+ isa_flag = csky_cpus[i].isa_flag;
+ break;
+ }
+ }
+#else
+#if _CSKY_ABI==1
+ mach_flag |= CSKY_ARCH_610 | flags;
+#else
+ mach_flag |= CSKY_ARCH_810_BASE | flags;
+#endif
+#endif
+ }
+
+ if (IS_CSKY_ARCH_610 (mach_flag) || IS_CSKY_ARCH_510 (mach_flag))
+ {
+ if ((mach_flag & CSKY_ARCH_MP) && (mach_flag & CSKY_ARCH_MAC))
+ as_fatal ("520/620 conflicts with -mmp option");
+ else if ((mach_flag & CSKY_ARCH_MP) && (mach_flag & CSKY_ARCH_DSP))
+ as_fatal ("510e/610e conflicts with -mmp option");
+ else if ((mach_flag & CSKY_ARCH_DSP) && (mach_flag & CSKY_ARCH_MAC))
+ as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
+ }
+ if (IS_CSKY_ARCH_510 (mach_flag) && (mach_flag & CSKY_ARCH_FLOAT))
+ {
+ mach_flag = (mach_flag & (~CSKY_ARCH_MASK));
+ mach_flag |= CSKY_ARCH_610;
+ }
+
+ /* Find bfd_mach_flag, it will set to bfd backend data. */
+ for (p_arch = csky_archs; p_arch->arch_flag != 0; p_arch++)
+ if ((mach_flag & CSKY_ARCH_MASK) == (p_arch->arch_flag & CSKY_ARCH_MASK))
+ {
+ bfd_mach_flag = p_arch->bfd_mach_flag;
+ break;
+ }
+
+ /* Find isa_flag. */
+ for (p_cpu = csky_cpus; p_cpu->mach_flag != 0; p_cpu++)
+ if ((mach_flag & CPU_ARCH_MASK) == p_cpu->mach_flag)
+ {
+ isa_flag |= p_cpu->isa_flag;
+ break;
+ }
+
+ /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
+ use enhanced dsp instruction. Otherwise, we will use normal dsp. */
+ if (dsp_flag)
+ {
+ if (IS_CSKY_ARCH_803 (mach_flag))
+ {
+ /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
+ if ((dsp_flag & CSKY_DSP_FLAG_V1) && (dsp_flag & CSKY_DSP_FLAG_V2))
+ as_warn (_("option -mdsp conflicts with -medsp, only enabling -medsp"));
+ isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
+ isa_flag |= CSKY_ISA_DSP_ENHANCE;
+ }
+ else
+ {
+ isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
+ as_warn (_("-medsp option is only supported by ck803s, ignoring -medsp"));
+ }
+ ;
+ }
+
+ if (do_use_branchstub == -1)
+ do_use_branchstub = !IS_CSKY_ARCH_V1 (mach_flag);
+ else if (do_use_branchstub == 1)
+ {
+ if (IS_CSKY_ARCH_V1 (mach_flag))
+ {
+ as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
+ do_use_branchstub = 0;
+ }
+ else if (do_force2bsr == 0)
+ {
+ as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
+ do_force2bsr = 1;
+ }
+ }
+
+ if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
+ {
+ if (!do_force2bsr)
+ as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
+ do_force2bsr = 1;
+ }
+ else if (do_force2bsr == -1)
+ do_force2bsr = do_use_branchstub;
+
+ if (do_pff == -1)
+ {
+ if (IS_CSKY_ARCH_V1 (mach_flag))
+ do_pff = 1;
+ else
+ do_pff = 0;
+ }
+
+ if (do_extend_lrw == -1)
+ {
+ if (IS_CSKY_ARCH_801 (mach_flag))
+ do_extend_lrw = 1;
+ else
+ do_extend_lrw = 0;
+ }
+ if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
+ {
+ if (do_long_jump > 0)
+ as_warn (_("-mljump is ignored for ck801/ck802"));
+ do_long_jump = 0;
+ }
+ else if (do_long_jump == -1)
+ do_long_jump = 1;
+ if (do_intr_stack == -1)
+ {
+ /* control interrupt stack module, 801&802&803 default on
+ 807&810, default off. */
+ if (IS_CSKY_ARCH_807 (mach_flag) || IS_CSKY_ARCH_810 (mach_flag))
+ do_intr_stack = 0;
+ else
+ do_intr_stack = 1;
+ }
+ /* TODO: add isa_flag(SIMP/CACHE/APS). */
+ isa_flag |= (mach_flag & CSKY_ARCH_MAC) ? CSKY_ISA_MAC : 0;
+ isa_flag |= (mach_flag & CSKY_ARCH_MP) ? CSKY_ISA_MP : 0;
+ isa_flag |= (mach_flag & CSKY_ARCH_CP) ? CSKY_ISA_CP : 0;
+
+ /* Set abi flag and get table address. */
+ if (IS_CSKY_ARCH_V1 (mach_flag))
+ {
+ mach_flag = mach_flag | CSKY_ABI_V1;
+ opcode = csky_v1_opcodes;
+ macro = v1_macros_table;
+ SPANPANIC = v1_SPANPANIC;
+ SPANCLOSE = v1_SPANCLOSE;
+ SPANEXIT = v1_SPANEXIT;
+ md_relax_table = csky_relax_table;
+ }
+ else
+ {
+ mach_flag = mach_flag | CSKY_ABI_V2;
+ opcode = csky_v2_opcodes;
+ macro = v2_macros_table;
+ SPANPANIC = v2_SPANPANIC;
+ if (do_extend_lrw)
+ {
+ SPANCLOSE = v2_SPANCLOSE_ELRW;
+ SPANEXIT = v2_SPANEXIT_ELRW;
+ }
+ else
+ {
+ SPANCLOSE = v2_SPANCLOSE;
+ SPANEXIT = v2_SPANEXIT;
+ }
+ md_relax_table = csky_relax_table;
+ }
+
+ /* Establish hash table for opcodes and macros. */
+ csky_macros_hash = hash_new ();
+ csky_opcodes_hash = hash_new ();
+ for ( ; opcode->mnemonic != NULL; opcode++)
+ if ((isa_flag & (opcode->isa_flag16 | opcode->isa_flag32)) != 0)
+ hash_insert (csky_opcodes_hash, opcode->mnemonic, (char *)opcode);
+ for ( ; macro->name != NULL; macro++)
+ if ((isa_flag & macro->isa_flag) != 0)
+ hash_insert (csky_macros_hash, macro->name, (char *)macro);
+ if (do_nolrw && (isa_flag & CSKYV2_ISA_1E2) != 0)
+ hash_insert (csky_macros_hash,
+ v2_lrw_macro_opcode.name,
+ (char *)&v2_lrw_macro_opcode);
+ /* Set e_flag to ELF Head. */
+ bfd_set_private_flags (stdoutput, mach_flag);
+ /* Set bfd_mach to bfd backend data. */
+ bfd_set_arch_mach (stdoutput, bfd_arch_csky, bfd_mach_flag);
+}
+
+/* The C-SKY assembler emits mapping symbols $t and $d to mark the
+ beginning of a sequence of instructions and data (such as a constant pool),
+ respectively. This is similar to what ARM does. */
+
+static void
+make_mapping_symbol (map_state state, valueT value, fragS *frag)
+{
+ symbolS * symbolP;
+ const char * symname;
+ int type;
+ switch (state)
+ {
+ case MAP_DATA:
+ symname = "$d";
+ type = BSF_NO_FLAGS;
+ break;
+ case MAP_TEXT:
+ symname = "$t";
+ type = BSF_NO_FLAGS;
+ break;
+ default:
+ abort ();
+ }
+
+ symbolP = symbol_new (symname, now_seg, value, frag);
+ symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
+}
+
+/* We need to keep track of whether we are emitting code or data; this
+ function switches state and emits a mapping symbol if necessary. */
+
+static void
+mapping_state (map_state state)
+{
+ map_state current_state
+ = seg_info (now_seg)->tc_segment_info_data.current_state;
+
+ if (current_state == state)
+ return;
+ else if (current_state == MAP_UNDEFINED && state == MAP_DATA)
+ return;
+ else if (current_state == MAP_UNDEFINED && state == MAP_TEXT)
+ {
+ struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
+ if (frag_now != frag_first || frag_now_fix () > 0)
+ make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
+ }
+
+ seg_info (now_seg)->tc_segment_info_data.current_state = state;
+ make_mapping_symbol (state, (valueT) frag_now_fix (), frag_now);
+}
+
+/* Dump the literal pool. */
+
+static void
+dump_literals (int isforce)
+{
+#define CSKYV1_BR_INSN 0xF000
+#define CSKYV2_BR_INSN 0x0400
+ unsigned int i;
+ struct literal * p;
+ symbolS * brarsym = NULL;
+
+ /* V1 nop encoding: 0x1200 : mov r0, r0. */
+ static char v1_nop_insn_big[2] = {0x12, 0x00};
+ static char v1_nop_insn_little[2] = {0x00, 0x12};
+
+ if (poolsize == 0)
+ return;
+
+ /* Must we branch around the literal table? */
+ if (isforce)
+ {
+ char brarname[8];
+ make_internal_label (brarname, POOL_END_LABEL, poolnumber);
+ brarsym = symbol_make (brarname);
+ symbol_table_insert (brarsym);
+ mapping_state (MAP_TEXT);
+ if (IS_CSKY_ARCH_V1 (mach_flag))
+ {
+ csky_insn.output
+ = frag_var (rs_machine_dependent,
+ csky_relax_table[C (UNCD_JUMP_S, DISP32)].rlx_length,
+ csky_relax_table[C (UNCD_JUMP_S, DISP12)].rlx_length,
+ C (UNCD_JUMP_S, 0), brarsym, 0, 0);
+ md_number_to_chars (csky_insn.output, CSKYV1_BR_INSN, 2);
+ }
+ else
+ {
+ csky_insn.output
+ = frag_var (rs_machine_dependent,
+ UNCD_DISP16_LEN,
+ UNCD_DISP10_LEN,
+ UNCD_DISP10,
+ brarsym, 0, 0);
+ md_number_to_chars (csky_insn.output, CSKYV2_BR_INSN, 2);
+ }
+ }
+ /* Make sure that the section is sufficiently aligned and that
+ the literal table is aligned within it. */
+ if (do_pff)
+ {
+ valueT br_self;
+ csky_insn.output = frag_more (2);
+ /* .Lxx: br .Lxx */
+ if (IS_CSKY_V1 (mach_flag))
+ br_self = CSKYV1_BR_INSN | 0x7ff;
+ else
+ br_self = CSKYV2_BR_INSN;
+ md_number_to_chars (csky_insn.output, br_self, 2);
+ if (!isforce)
+ {
+ csky_insn.output = frag_more (2);
+ /* .Lxx: br .Lxx */
+ md_number_to_chars (csky_insn.output, br_self, 2);
+ }
+ }
+ mapping_state (MAP_DATA);
+
+ record_alignment (now_seg, 2);
+ if (IS_CSKY_ARCH_V1 (mach_flag))
+ frag_align_pattern (2,
+ (target_big_endian
+ ? v1_nop_insn_big : v1_nop_insn_little),
+ 2, 0);
+ else
+ frag_align (2, 0, 3);
+
+ colon (S_GET_NAME (poolsym));
+
+ for (i = 0, p = litpool; i < poolsize; i += (p->isdouble ? 2 : 1), p++)
+ {
+ insn_reloc = p->r_type;
+ if (insn_reloc == BFD_RELOC_CKCORE_TLS_IE32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_GD32)
+ literal_insn_offset = p;
+ if (p->isdouble)
+ {
+ if (target_big_endian)
+ {
+ p->e.X_add_number = p->dbnum >> 32;
+ emit_expr (& p->e, 4);
+ p->e.X_add_number = p->dbnum & 0xffffffff;
+ emit_expr (& p->e, 4);
+ }
+ else
+ {
+ p->e.X_add_number = p->dbnum & 0xffffffff;
+ emit_expr (& p->e, 4);
+ p->e.X_add_number = p->dbnum >> 32;
+ emit_expr (& p->e, 4);
+ }
+ }
+ else
+ emit_expr (& p->e, 4);
+ }
+
+ if (isforce && IS_CSKY_ARCH_V2 (mach_flag))
+ {
+ /* Add one nop insn at end of literal for disassembler. */
+ mapping_state (MAP_TEXT);
+ csky_insn.output = frag_more (2);
+ md_number_to_chars (csky_insn.output, CSKYV2_INST_NOP, 2);
+ }
+
+ insn_reloc = BFD_RELOC_NONE;
+
+ if (brarsym != NULL)
+ colon (S_GET_NAME (brarsym));
+ poolsize = 0;
+}
+
+static int
+enter_literal (expressionS *e,
+ int ispcrel,
+ unsigned char isdouble,
+ uint64_t dbnum)
+{
+ unsigned int i;
+ struct literal * p;
+ if (poolsize >= MAX_POOL_SIZE - 2)
+ {
+ /* The literal pool is as full as we can handle. We have
+ to be 2 entries shy of the 1024/4=256 entries because we
+ have to allow for the branch (2 bytes) and the alignment
+ (2 bytes before the first insn referencing the pool and
+ 2 bytes before the pool itself) == 6 bytes, rounds up
+ to 2 entries. */
+
+ /* Save the parsed symbol's reloc. */
+ enum bfd_reloc_code_real last_reloc_before_dump = insn_reloc;
+ dump_literals (1);
+ insn_reloc = last_reloc_before_dump;
+ }
+
+ if (poolsize == 0)
+ {
+ /* Create new literal pool. */
+ if (++ poolnumber > 0xFFFF)
+ as_fatal (_("more than 65K literal pools"));
+
+ make_internal_label (poolname, POOL_START_LABEL, poolnumber);
+ poolsym = symbol_make (poolname);
+ symbol_table_insert (poolsym);
+ poolspan = 0;
+ }
+
+ /* Search pool for value so we don't have duplicates. */
+ for (p = litpool, i = 0; i < poolsize; i += (p->isdouble ? 2 : 1), p++)
+ {
+ if (e->X_op == p->e.X_op
+ && e->X_add_symbol == p->e.X_add_symbol
+ && e->X_add_number == p->e.X_add_number
+ && ispcrel == p->ispcrel
+ && insn_reloc == p->r_type
+ && isdouble == p->isdouble
+ && insn_reloc != BFD_RELOC_CKCORE_TLS_GD32
+ && insn_reloc != BFD_RELOC_CKCORE_TLS_LDM32
+ && insn_reloc != BFD_RELOC_CKCORE_TLS_LDO32
+ && insn_reloc != BFD_RELOC_CKCORE_TLS_IE32
+ && insn_reloc != BFD_RELOC_CKCORE_TLS_LE32)
+ {
+ p->refcnt ++;
+ return i;
+ }
+ }
+ p->refcnt = 1;
+ p->ispcrel = ispcrel;
+ p->e = *e;
+ p->r_type = insn_reloc;
+ p->isdouble = isdouble;
+ if (isdouble)
+ p->dbnum = dbnum;
+
+ if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
+ {
+ p->tls_addend.frag = frag_now;
+ p->tls_addend.offset = csky_insn.output - frag_now->fr_literal;
+ literal_insn_offset = p;
+ }
+ poolsize += (p->isdouble ? 2 : 1);
+ return i;
+}
+
+/* Check whether we must dump the literal pool here.
+ kind == 0 is any old instruction.
+ kind > 0 means we just had a control transfer instruction.
+ kind == 1 means within a function.
+ kind == 2 means we just left a function.
+
+ OFFSET is the length of the insn being processed.
+
+ SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
+ SPANPANIC means that we must dump now.
+ The dump_literals (1) call inserts a branch around the table, so
+ we first look to see if its a situation where we won't have to
+ insert a branch (e.g., the previous instruction was an unconditional
+ branch).
+
+ SPANPANIC is the point where we must dump a single-entry pool.
+ it accounts for alignments and an inserted branch.
+ the 'poolsize*2' accounts for the scenario where we do:
+ lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
+ Note that the 'lit2' reference is 2 bytes further along
+ but the literal it references will be 4 bytes further along,
+ so we must consider the poolsize into this equation.
+ This is slightly over-cautious, but guarantees that we won't
+ panic because a relocation is too distant. */
+
+static void
+check_literals (int kind, int offset)
+{
+ poolspan += offset;
+
+ if ((poolspan > SPANEXIT || do_func_dump)
+ && kind > 1
+ && (do_br_dump || do_func_dump))
+ dump_literals (0);
+ else if (poolspan > SPANCLOSE && (kind > 0) && do_br_dump)
+ dump_literals (0);
+ else if (poolspan
+ >= (SPANPANIC - (IS_CSKY_ARCH_V1 (mach_flag) ? poolsize * 2 : 0)))
+ dump_literals (1);
+ /* We have not dumped literal pool before insn1,
+ and will not dump literal pool between insn1 and insnN+1,
+ so reset poolspan to original length. */
+ else if (do_noliteraldump == 1)
+ poolspan -= offset;
+
+ if (do_noliteraldump == 1)
+ do_noliteraldump = 0;
+}
+
+/* The next group of functions are helpers for parsing various kinds
+ of instruction operand syntax. */
+
+/* Parse operands of the form
+ <symbol>@GOTOFF+<nnn>
+ and similar .plt or .got references.
+
+ If we find one, set up the correct relocation in RELOC and copy the
+ input string, minus the `@GOTOFF' into a malloc'd buffer for
+ parsing by the calling routine. Return this buffer, and if ADJUST
+ is non-null set it to the length of the string we removed from the
+ input line. Otherwise return NULL. */
+
+static char *
+lex_got (enum bfd_reloc_code_real *reloc,
+ int *adjust)
+{
+ struct _gotrel
+ {
+ const char *str;
+ const enum bfd_reloc_code_real rel;
+ };
+ static const struct _gotrel gotrel[] =
+ {
+ { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF },
+ { "GOTPC", BFD_RELOC_CKCORE_GOTPC },
+ { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32 },
+ { "GOT", BFD_RELOC_CKCORE_GOT32 },
+ { "PLT", BFD_RELOC_CKCORE_PLT32 },
+ { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16},
+ { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16},
+ { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32 },
+ { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32 },
+ { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32 },
+ { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32 }
+ };
+
+ char *cp;
+ unsigned int j;
+
+ for (cp = input_line_pointer; *cp != '@'; cp++)
+ if (is_end_of_line[(unsigned char) *cp])
+ return NULL;
+
+ for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)
+ {
+ int len = strlen (gotrel[j].str);
+
+ if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
+ {
+ if (gotrel[j].rel != 0)
+ {
+ *reloc = gotrel[j].rel;
+ if (adjust)
+ *adjust = len;
+
+ /* input_line_pointer is the str pointer after relocation
+ token like @GOTOFF. */
+ input_line_pointer += len + 1;
+ return input_line_pointer;
+ }
+
+ csky_show_error (ERROR_RELOC_ILLEGAL, 0,
+ (void *)gotrel[j].str, NULL);
+ return NULL;
+ }
+ }
+
+ /* Might be a symbol version string. Don't as_bad here. */
+ return NULL;
+}
+
+/* Parse an expression, returning it in E. */
+
+static char *
+parse_exp (char *s, expressionS *e)
+{
+ char *save;
+ char *new;
+
+ /* Skip whitespace. */
+ while (ISSPACE (*s))
+ ++s;
+
+ save = input_line_pointer;
+ input_line_pointer = s;
+
+ insn_reloc = BFD_RELOC_NONE;
+ expression (e);
+ lex_got (&insn_reloc, NULL);
+
+ if (e->X_op == O_absent)
+ SET_ERROR_NUMBER (ERROR_MISSING_OPERAND, NULL);
+
+ new = input_line_pointer;
+ input_line_pointer = save;
+
+ return new;
+}
+
+/* Parse a floating-point number from S into its target representation.
+ If ISDOUBLE is true, return the result in *DBNUM; otherwise
+ it's returned in E->X_add_number. Returns the result of advancing
+ S past the constant. */
+
+static char *
+parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
+{
+ int length; /* Number of chars in an object. */
+ register char const *err = NULL; /* Error from scanning float literal. */
+ char temp[8];
+
+ /* input_line_pointer->1st char of a flonum (we hope!). */
+ input_line_pointer = s;
+
+ if (input_line_pointer[0] == '0'
+ && ISALPHA (input_line_pointer[1]))
+ input_line_pointer += 2;
+
+ if (isdouble)
+ err = md_atof ('d', temp, &length);
+ else
+ err = md_atof ('f', temp, &length);
+ know (length <= 8);
+ know (err != NULL || length > 0);
+
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
+ as_bad (_("immediate operand required"));
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ input_line_pointer++;
+
+ if (err)
+ {
+ as_bad (_("bad floating literal: %s"), err);
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ input_line_pointer++;
+ know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
+ return input_line_pointer;
+ }
+
+ e->X_add_symbol = 0x0;
+ e->X_op_symbol = 0x0;
+ e->X_op = O_constant;
+ e->X_unsigned = 1;
+ e->X_md = 0x0;
+
+ if (!isdouble)
+ {
+ uint32_t fnum;
+ if (target_big_endian)
+ fnum = (((temp[0] << 24) & 0xffffffff)
+ | ((temp[1] << 16) & 0xffffff)
+ | ((temp[2] << 8) & 0xffff)
+ | (temp[3] & 0xff));
+ else
+ fnum = (((temp[3] << 24) & 0xffffffff)
+ | ((temp[2] << 16) & 0xffffff)
+ | ((temp[1] << 8) & 0xffff)
+ | (temp[0] & 0xff));
+ e->X_add_number = fnum; }
+ else
+ {
+ if (target_big_endian)
+ {
+ *dbnum = (((temp[0] << 24) & 0xffffffff)
+ | ((temp[1] << 16) & 0xffffff)
+ | ((temp[2] << 8) & 0xffff)
+ | (temp[3] & 0xff));
+ *dbnum <<= 32;
+ *dbnum |= (((temp[4] << 24) & 0xffffffff)
+ | ((temp[5] << 16) & 0xffffff)
+ | ((temp[6] << 8) & 0xffff)
+ | (temp[7] & 0xff));
+ }
+ else
+ {
+ *dbnum = (((temp[7] << 24) & 0xffffffff)
+ | ((temp[6] << 16) & 0xffffff)
+ | ((temp[5] << 8) & 0xffff)
+ | (temp[4] & 0xff));
+ *dbnum <<= 32;
+ *dbnum |= (((temp[3] << 24) & 0xffffffff)
+ | ((temp[2] << 16) & 0xffffff)
+ | ((temp[1] << 8) & 0xffff)
+ | (temp[0] & 0xff));
+ }
+ }
+ return input_line_pointer;
+}
+
+static char *
+parse_rt (char *s,
+ int ispcrel,
+ expressionS *ep,
+ long reg ATTRIBUTE_UNUSED)
+{
+ expressionS e;
+ int n;
+
+ if (ep)
+ /* Indicate nothing there. */
+ ep->X_op = O_absent;
+
+ if (*s == '[')
+ {
+ s = parse_exp (s + 1, &e);
+
+ if (*s == ']')
+ s++;
+ else
+ SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
+
+ if (ep)
+ *ep = e;
+ }
+ else
+ {
+ s = parse_exp (s, &e);
+ if (BFD_RELOC_CKCORE_DOFFSET_LO16 == insn_reloc
+ || BFD_RELOC_CKCORE_TOFFSET_LO16 == insn_reloc)
+ {
+ if (ep)
+ *ep = e;
+ return s;
+ }
+ if (ep)
+ *ep = e;
+ /* If the instruction has work, literal handling is in the work. */
+ if (!csky_insn.opcode->work)
+ {
+ n = enter_literal (&e, ispcrel, 0, 0);
+ if (ep)
+ *ep = e;
+
+ /* Create a reference to pool entry. */
+ ep->X_op = O_symbol;
+ ep->X_add_symbol = poolsym;
+ ep->X_add_number = n << 2;
+ }
+ }
+ return s;
+}
+
+static char *
+parse_rtf (char *s, int ispcrel, expressionS *ep)
+{
+ expressionS e;
+ int n = 0;
+
+ if (ep)
+ /* Indicate nothing there. */
+ ep->X_op = O_absent;
+
+ if (*s == '[')
+ {
+ s = parse_exp (s + 1, & e);
+
+ if (*s == ']')
+ s++;
+ else
+ as_bad (_("missing ']'"));
+
+ if (ep)
+ *ep = e;
+ }
+ else
+ {
+ uint64_t dbnum;
+ if (strstr (csky_insn.opcode->mnemonic, "flrws"))
+ {
+ s = parse_fexp (s, &e, 0, &dbnum);
+ n = enter_literal (&e, ispcrel, 0, dbnum);
+ }
+ else if (strstr (csky_insn.opcode->mnemonic, "flrwd"))
+ {
+ s = parse_fexp (s, &e, 1, &dbnum);
+ n = enter_literal (&e, ispcrel, 1, dbnum);
+ }
+ else
+ as_bad (_("unrecognized opcode"));
+
+ if (ep)
+ *ep = e;
+
+ /* Create a reference to pool entry. */
+ ep->X_op = O_symbol;
+ ep->X_add_symbol = poolsym;
+ ep->X_add_number = n << 2;
+ }
+ return s;
+}
+
+static bfd_boolean
+parse_type_ctrlreg (char** oper)
+{
+ int i = -1;
+ int len = 0;
+
+ if (TOLOWER (*(*oper + 0)) == 'c'
+ && TOLOWER (*(*oper + 1)) == 'r'
+ && ISDIGIT (*(*oper + 2)))
+ {
+ /* The control registers are named crxx. */
+ i = *(*oper + 2) - 0x30;
+ i = ISDIGIT (*(*oper + 3)) ? (*(*oper + 3) - 0x30) + 10 * i : i;
+ len = ISDIGIT (*(*oper + 3)) ? 4 : 3;
+ *oper += len;
+ }
+ else if (!(TOLOWER (*(*oper + 0)) == 'c'
+ && TOLOWER (*(*oper + 1)) == 'r'))
+ {
+ /* The control registers are aliased. */
+ struct csky_reg *reg = &csky_ctrl_regs[0];
+ while (reg->name)
+ {
+ if (memcmp (*oper, reg->name, strlen (reg->name)) == 0
+ && (!reg->flag || (isa_flag & reg->flag)))
+ {
+ i = reg->index;
+ len = strlen (reg->name);
+ *oper += len;
+ break;
+ }
+ reg++;
+ }
+ }
+
+ if (IS_CSKY_V2 (mach_flag))
+ {
+ char *s = *oper;
+ int crx;
+ int sel;
+ if (i != -1)
+ {
+ crx = i;
+ sel = 0;
+ }
+ else
+ {
+ if (s[0] == 'c' && s[1] == 'r')
+ {
+ s += 2;
+ if (*s == '<')
+ {
+ s++;
+ if (s[0] == '3' && s[1] >= '0' && s[1] <= '1')
+ {
+ crx = 30 + s[1] - '0';
+ s += 2;
+ }
+ else if (s[0] == '2' && s[1] >= '0' && s[1] <= '9')
+ {
+ crx = 20 + s[1] - '0';
+ s += 2;
+ }
+ else if (s[0] == '1' && s[1] >= '0' && s[1] <= '9')
+ {
+ crx = 10 + s[1] - '0';
+ s += 2;
+ }
+ else if (s[0] >= '0' && s[0] <= '9')
+ {
+ crx = s[0] - '0';
+ s += 1;
+ }
+ else
+ {
+ SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, "control");
+ return FALSE;
+ }
+ if (*s == ',')
+ s++;
+ else
+ {
+ SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL, NULL);
+ return FALSE;
+ }
+ char *pS = s;
+ while (*pS != '>' && !is_end_of_line[(unsigned char) *pS])
+ pS++;
+ if (*pS == '>')
+ *pS = '\0';
+ else
+ {
+ /* Error. Missing '>'. */
+ SET_ERROR_NUMBER (ERROR_MISSING_RANGLE_BRACKETS, NULL);
+ return FALSE;
+ }
+ expressionS e;
+ s = parse_exp (s, &e);
+ if (e.X_op == O_constant
+ && e.X_add_number >= 0
+ && e.X_add_number <= 31)
+ {
+ *oper = s;
+ sel = e.X_add_number;
+ }
+ else
+ return FALSE;
+ }
+ else
+ {
+ /* Error. Missing '<'. */
+ SET_ERROR_NUMBER (ERROR_MISSING_LANGLE_BRACKETS, NULL);
+ return FALSE;
+ }
+ }
+ else
+ {
+ SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL, NULL);
+ return FALSE;
+ }
+ }
+ i = (sel << 5) | crx;
+ }
+ csky_insn.val[csky_insn.idx++] = i;
+ return TRUE;
+}
+
+static bfd_boolean
+is_reg_sp_with_bracket (char **oper)
+{
+ const char **regs;
+ int sp_idx;
+ int len;
+
+ if (IS_CSKY_V1 (mach_flag))
+ sp_idx = 0;
+ else
+ sp_idx = 14;
+
+ if (**oper != '(')
+ return FALSE;
+ *oper += 1;
+ regs = csky_general_reg;
+ len = strlen (regs[sp_idx]);
+ if (memcmp (*oper, regs[sp_idx], len) == 0)
+ {
+ *oper += len;
+ if (**oper != ')')
+ return FALSE;
+ *oper += 1;
+ csky_insn.val[csky_insn.idx++] = sp_idx;
+ return TRUE;
+ }
+ else
+ {
+ if (IS_CSKY_V1 (mach_flag))
+ regs = cskyv1_general_alias_reg;
+ else
+ regs = cskyv2_general_alias_reg;
+ len = strlen (regs[sp_idx]);
+ if (memcmp (*oper, regs[sp_idx], len) == 0)
+ {
+ *oper += len;
+ if (**oper != ')')
+ return FALSE;
+ *oper += 1;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static bfd_boolean
+is_reg_sp (char **oper)
+{
+ const char **regs;
+ int sp_idx;
+ int len;
+ if (IS_CSKY_V1 (mach_flag))
+ sp_idx = 0;
+ else
+ sp_idx = 14;
+
+ regs = csky_general_reg;
+ len = strlen (regs[sp_idx]);
+ if (memcmp (*oper, regs[sp_idx], len) == 0)
+ {
+ *oper += len;
+ csky_insn.val[csky_insn.idx++] = sp_idx;
+ return TRUE;
+ }
+ else
+ {
+ if (IS_CSKY_V1 (mach_flag))
+ regs = cskyv1_general_alias_reg;
+ else
+ regs = cskyv2_general_alias_reg;
+ len = strlen (regs[sp_idx]);
+ if (memcmp (*oper, regs[sp_idx], len) == 0)
+ {
+ *oper += len;
+ csky_insn.val[csky_insn.idx++] = sp_idx;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static int
+csky_get_reg_val (char *str, int *len)
+{
+ long reg = 0;
+ if (TOLOWER (str[0]) == 'r' && ISDIGIT (str[1]))
+ {
+ if (ISDIGIT (str[1]) && ISDIGIT (str[2]))
+ {
+ reg = (str[1] - '0') * 10 + str[2] - '0';
+ *len = 3;
+ }
+ else if (ISDIGIT (str[1]))
+ {
+ reg = str[1] - '0';
+ *len = 2;
+ }
+ else
+ return -1;
+ }
+ else if (TOLOWER (str[0]) == 's' && TOLOWER (str[1]) == 'p'
+ && !ISDIGIT (str[2]))
+ {
+ /* sp. */
+ if (IS_CSKY_V1 (mach_flag))
+ reg = 0;
+ else
+ reg = 14;
+ *len = 2;
+ }
+ else if (TOLOWER (str[0]) == 'g' && TOLOWER (str[1]) == 'b'
+ && !ISDIGIT (str[2]))
+ {
+ /* gb. */
+ if (IS_CSKY_V1 (mach_flag))
+ reg = 14;
+ else
+ reg = 28;
+ *len = 2;
+ }
+ else if (TOLOWER (str[0]) == 'l' && TOLOWER (str[1]) == 'r'
+ && !ISDIGIT (str[2]))
+ {
+ /* lr. */
+ reg = 15;
+ *len = 2;
+ }
+ else if (TOLOWER (str[0]) == 't' && TOLOWER (str[1]) == 'l'
+ && TOLOWER (str[2]) == 's' && !ISDIGIT (str[3]))
+ {
+ /* tls. */
+ if (IS_CSKY_V2 (mach_flag))
+ reg = 31;
+ else
+ return -1;
+ *len = 3;
+ }
+ else if (TOLOWER (str[0]) == 's' && TOLOWER (str[1]) == 'v'
+ && TOLOWER (str[2]) == 'b' && TOLOWER (str[3]) == 'r')
+ {
+ if (IS_CSKY_V2 (mach_flag))
+ reg = 30;
+ else
+ return -1;
+ *len = 4;
+ }
+ else if (TOLOWER (str[0]) == 'a')
+ {
+ if (ISDIGIT (str[1]) && !ISDIGIT (str[2]))
+ {
+ if (IS_CSKY_V1 (mach_flag) && (str[1] - '0') <= 5)
+ /* a0 - a5. */
+ reg = 2 + str[1] - '0';
+ else if (IS_CSKY_V2 (mach_flag) && (str[1] - '0') <= 3)
+ /* a0 - a3. */
+ reg = str[1] - '0';
+ else
+ return -1;
+ *len = 2;
+ }
+ }
+ else if (TOLOWER (str[0]) == 't')
+ {
+ if (IS_CSKY_V2 (mach_flag))
+ {
+ reg = atoi (str + 1);
+ if (reg > 9)
+ return -1;
+
+ if (reg > 1)
+ /* t2 - t9. */
+ reg = reg + 16;
+ else
+ /* t0 - t1. */
+ reg = reg + 12;
+ *len = 2;
+ }
+ }
+ else if (TOLOWER (str[0]) == 'l')
+ {
+ if (str[1] < '0' || str[1] > '9')
+ return -1;
+ if (IS_CSKY_V2 (mach_flag))
+ {
+ reg = atoi (str + 1);
+ if (reg > 9)
+ return -1;
+ if (reg > 7)
+ /* l8 - l9. */
+ reg = reg + 8;
+ else
+ /* l0 - l7. */
+ reg = reg + 4;
+ }
+ else
+ {
+ reg = atoi (str + 1);
+ if (reg > 5)
+ return -1;
+ /* l0 - l6 -> r8 - r13. */
+ reg = reg + 8;
+ }
+ *len = 2;
+ }
+ else
+ return -1;
+
+ /* Is register available? */
+ if (IS_CSKY_ARCH_801 (mach_flag))
+ {
+ /* CK801 register range is r0-r8 & r13-r15. */
+ if ((reg > 8 && reg < 13) || reg > 15)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
+ return -1;
+ }
+ }
+ else if (IS_CSKY_ARCH_802 (mach_flag))
+ {
+ /* CK802 register range is r0-r15 & r23-r25 & r30. */
+ if ((reg > 15 && reg < 23) || (reg > 25 && reg != 30))
+ {
+ SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
+ return -1;
+ }
+ }
+ else if (reg > 31 || reg < 0)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
+ return -1;
+ }
+
+ return reg;
+}
+
+static int
+csky_get_freg_val (char *str, int *len)
+{
+ int reg = 0;
+ char *s = NULL;
+ if ((str[0] == 'v' || str[0] == 'f') && (str[1] == 'r'))
+ {
+ /* It is fpu register. */
+ s = &str[2];
+ while (ISDIGIT (*s))
+ {
+ reg = reg * 10 + (*s) - '0';
+ s++;
+ }
+ if (reg > 31)
+ return -1;
+ }
+ else
+ return -1;
+ *len = s - str;
+ return reg;
+}
+
+static bfd_boolean
+is_reglist_legal (char **oper)
+{
+ int reg1 = -1;
+ int reg2 = -1;
+ int len = 0;
+ reg1 = csky_get_reg_val (*oper, &len);
+ *oper += len;
+
+ if (reg1 == -1 || (IS_CSKY_V1 (mach_flag) && (reg1 == 0 || reg1 == 15)))
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The first reg must not be r0/r15");
+ return FALSE;
+ }
+
+ if (**oper != '-')
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The operand format must be rx-ry");
+ return FALSE;
+ }
+ *oper += 1;
+
+ reg2 = csky_get_reg_val (*oper, &len);
+ *oper += len;
+
+ if (reg2 == -1 || (IS_CSKY_V1 (mach_flag) && reg1 == 15))
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The operand format must be r15 in C-SKY V1");
+ return FALSE;
+ }
+ if (IS_CSKY_V2 (mach_flag))
+ {
+ if (reg2 < reg1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The operand format must be rx-ry (rx < ry)");
+ return FALSE;
+ }
+ reg2 = reg2 - reg1;
+ reg1 <<= 5;
+ reg1 |= reg2;
+ }
+ csky_insn.val[csky_insn.idx++] = reg1;
+ return TRUE;
+}
+
+static bfd_boolean
+is_freglist_legal (char **oper)
+{
+ int reg1 = -1;
+ int reg2 = -1;
+ int len = 0;
+ reg1 = csky_get_freg_val (*oper, &len);
+ *oper += len;
+
+ if (reg1 == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The fpu register format is not recognized.");
+ return FALSE;
+ }
+
+ if (**oper != '-')
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The operand format must be vrx-vry/frx-fry.");
+ return FALSE;
+ }
+ *oper += 1;
+
+ reg2 = csky_get_freg_val (*oper, &len);
+ *oper += len;
+
+ if (reg2 == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The fpu register format is not recognized.");
+ return FALSE;
+ }
+ if (reg2 < reg1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The operand format must be rx-ry(rx < ry)");
+ return FALSE;
+ }
+ reg2 = reg2 - reg1;
+ reg2 <<= 4;
+ reg1 |= reg2;
+ csky_insn.val[csky_insn.idx++] = reg1;
+ return TRUE;
+}
+
+static bfd_boolean
+is_reglist_dash_comma_legal (char **oper, struct operand *oprnd)
+{
+ int reg1 = -1;
+ int reg2 = -1;
+ int len = 0;
+ int list = 0;
+ int flag = 0;
+ int temp = 0;
+ while (**oper != '\n' && **oper != '\0')
+ {
+ reg1 = csky_get_reg_val (*oper, &len);
+ if (reg1 == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
+ return FALSE;
+ }
+ flag |= (1 << reg1);
+ *oper += len;
+ if (**oper == '-')
+ {
+ *oper += 1;
+ reg2 = csky_get_reg_val (*oper, &len);
+ if (reg2 == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
+ return FALSE;
+ }
+ *oper += len;
+ if (reg1 > reg2)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
+ return FALSE;
+ }
+ while (reg2 >= reg1)
+ {
+ flag |= (1 << reg2);
+ reg2--;
+ }
+ }
+ if (**oper == ',')
+ *oper += 1;
+ }
+ /* The reglist: r4-r11, r15, r16-r17, r28. */
+#define REGLIST_BITS 0x10038ff0
+ if (flag & ~(REGLIST_BITS))
+ {
+ SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
+ return FALSE;
+ }
+ /* Check r4-r11. */
+ int i = 4;
+ while (i <= 11)
+ {
+ if (flag & (1 << i))
+ temp = i - 4 + 1;
+ i++;
+ }
+ list |= temp;
+
+ /* Check r15. */
+ if (flag & (1 << 15))
+ list |= (1 << 4);
+
+ /* Check r16-r17. */
+ i = 16;
+ temp = 0;
+ while (i <= 17)
+ {
+ if (flag & (1 << i))
+ temp = i - 16 + 1;
+ i++;
+ }
+ list |= (temp << 5);
+
+ /* Check r28. */
+ if (flag & (1 << 28))
+ list |= (1 << 8);
+ if (oprnd->mask == OPRND_MASK_0_4 && (list & ~OPRND_MASK_0_4))
+ {
+ SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
+ return FALSE;
+ }
+ csky_insn.val[csky_insn.idx++] = list;
+ return TRUE;
+}
+
+static bfd_boolean
+is_reg_lshift_illegal (char **oper, int is_float)
+{
+ int value;
+ int len;
+ int reg;
+ reg = csky_get_reg_val (*oper, &len);
+ if (reg == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT, "The register must be r0-r31.");
+ return FALSE;
+ }
+
+ *oper += len;
+ if ((*oper)[0] != '<' || (*oper)[1] != '<')
+ {
+ SET_ERROR_NUMBER (ERROR_UNDEFINE,
+ "Operand format error; should be (rx, ry << n)");
+ return FALSE;
+ }
+ *oper += 2;
+
+ expressionS e;
+ char *new_oper = parse_exp (*oper, &e);
+ if (e.X_op == O_constant)
+ {
+ *oper = new_oper;
+ /* The immediate must be in [0, 3]. */
+ if (e.X_add_number < 0 || e.X_add_number > 3)
+ {
+ SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
+ return FALSE;
+ }
+ }
+ else
+ {
+ SET_ERROR_NUMBER (ERROR_EXP_CONSTANT, NULL);
+ return FALSE;
+ }
+ if (is_float)
+ value = (reg << 2) | e.X_add_number;
+ else
+ value = (reg << 5) | (1 << e.X_add_number);
+ csky_insn.val[csky_insn.idx++] = value;
+
+ return TRUE;
+}
+
+static bfd_boolean
+is_imm_over_range (char **oper, int min, int max, int ext)
+{
+ expressionS e;
+ bfd_boolean ret = FALSE;
+ char *new_oper = parse_exp (*oper, &e);
+ if (e.X_op == O_constant)
+ {
+ ret = TRUE;
+ *oper = new_oper;
+ if ((int)e.X_add_number != ext
+ && (e.X_add_number < min || e.X_add_number > max))
+ {
+ ret = FALSE;
+ SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
+ }
+ csky_insn.val[csky_insn.idx++] = e.X_add_number;
+ }
+
+ return ret;
+}
+
+static bfd_boolean
+is_oimm_over_range (char **oper, int min, int max)
+{
+ expressionS e;
+ bfd_boolean ret = FALSE;
+ char *new_oper = parse_exp (*oper, &e);
+ if (e.X_op == O_constant)
+ {
+ ret = TRUE;
+ *oper = new_oper;
+ if (e.X_add_number < min || e.X_add_number > max)
+ {
+ ret = FALSE;
+ SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
+ }
+ csky_insn.val[csky_insn.idx++] = e.X_add_number - 1;
+ }
+
+ return ret;
+}
+
+static bfd_boolean
+is_psr_bit (char **oper)
+{
+ const struct psrbit *bits;
+ int i = 0;
+
+ if (IS_CSKY_V1 (mach_flag))
+ bits = cskyv1_psr_bits;
+ else
+ bits = cskyv2_psr_bits;
+
+ while (bits[i].name != NULL)
+ {
+ if (bits[i].isa && !(bits[i].isa & isa_flag))
+ {
+ i++;
+ continue;
+ }
+ if (strncasecmp (*oper, bits[i].name, strlen (bits[i].name)) == 0)
+ {
+ *oper += strlen (bits[i].name);
+ csky_insn.val[csky_insn.idx] |= bits[i].value;
+ return TRUE;
+ }
+ i++;
+ }
+ SET_ERROR_NUMBER (ERROR_OPCODE_PSRBIT, NULL);
+ return FALSE;
+}
+
+static bfd_boolean
+parse_type_cpidx (char** oper)
+{
+ char *s = *oper;
+ int idx;
+ if (s[0] == 'c' && s[1] == 'p')
+ {
+ if (ISDIGIT (s[2]) && ISDIGIT (s[3]) && ! ISDIGIT (s[4]))
+ {
+ idx = (s[2] - '0') * 10 + s[3] - '0';
+ *oper += 4;
+ }
+ else if (ISDIGIT (s[2]) && !ISDIGIT (s[3]))
+ {
+ idx = s[2] - '0';
+ *oper += 3;
+ }
+ else
+ return FALSE;
+ }
+ else
+ {
+ expressionS e;
+ *oper = parse_exp (*oper, &e);
+ if (e.X_op != O_constant)
+ {
+ /* Can not recognize the operand. */
+ return FALSE;
+ }
+ idx = e.X_add_number;
+ }
+
+ csky_insn.val[csky_insn.idx++] = idx;
+
+ return TRUE;
+}
+
+static bfd_boolean
+parse_type_cpreg (char** oper)
+{
+ const char **regs = csky_cp_reg;
+ int i;
+ int len;
+
+ for (i = 0; i < (int)(sizeof (csky_cp_reg) / sizeof (char *)); i++)
+ {
+ len = strlen (regs[i]);
+ if (memcmp (*oper, regs[i], len) == 0 && !ISDIGIT (*(*oper + len)))
+ {
+ *oper += len;
+ csky_insn.val[csky_insn.idx++] = i;
+ return TRUE;
+ }
+ }
+ SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL, *oper);
+ return FALSE;
+}
+
+static bfd_boolean
+parse_type_cpcreg (char** oper)
+{
+ const char **regs;
+ int i;
+ int len;
+ regs = csky_cp_creg;
+ for (i = 0; i < (int)(sizeof (csky_cp_creg) / sizeof (char *)); i++)
+ {
+ len = strlen (regs[i]);
+ if (memcmp (*oper, regs[i], len) == 0 && !ISDIGIT (*(*oper + len)))
+ {
+ *oper += len;
+ csky_insn.val[csky_insn.idx++] = i;
+ return TRUE;
+ }
+ }
+ SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL, *oper);
+ return FALSE;
+}
+
+static bfd_boolean
+parse_type_areg (char** oper)
+{
+ int i = 0;
+ int len = 0;
+ i = csky_get_reg_val (*oper, &len);
+ if (i == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL);
+ return FALSE;
+ }
+ *oper += len;
+ csky_insn.val[csky_insn.idx++] = i;
+
+ return TRUE;
+}
+
+static bfd_boolean
+parse_type_freg (char** oper, int even)
+{
+ int reg;
+ int len;
+ reg = csky_get_freg_val (*oper, &len);
+ if (reg == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The fpu register format is not recognized.");
+ return FALSE;
+ }
+ *oper += len;
+ csky_insn.opcode_end = *oper;
+ if (even && reg & 0x1)
+ {
+ SET_ERROR_NUMBER (ERROR_EXP_EVEN_FREG, NULL);
+ return FALSE;
+ }
+ csky_insn.val[csky_insn.idx++] = reg;
+ return TRUE;
+}
+
+static bfd_boolean
+parse_ldst_imm (char **oper, struct csky_opcode_info *op ATTRIBUTE_UNUSED,
+ struct operand *oprnd)
+{
+ unsigned int mask = oprnd->mask;
+ int max = 1;
+ int shift = 0;
+
+ shift = oprnd->shift;
+
+ while (mask)
+ {
+ if (mask & 1)
+ max <<= 1;
+ mask >>= 1;
+ }
+ max = max << shift;
+
+ if (**oper == '\0' || **oper == ')')
+ {
+ csky_insn.val[csky_insn.idx++] = 0;
+ return TRUE;
+ }
+
+ expressionS e;
+ *oper = parse_exp (*oper, &e);
+ if (e.X_op != O_constant)
+ /* Not a constant. */
+ return FALSE;
+ else if (e.X_add_number < 0 || e.X_add_number >= max)
+ {
+ /* Out of range. */
+ SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
+ return FALSE;
+ }
+ if ((e.X_add_number % (1 << shift)) != 0)
+ {
+ /* Not aligned. */
+ SET_ERROR_NUMBER (ERROR_OFFSET_UNALIGNED, ((unsigned long)1 << shift));
+ return FALSE;
+ }
+
+ csky_insn.val[csky_insn.idx++] = e.X_add_number >> shift;
+
+ return TRUE;
+
+}
+
+static unsigned int
+csky_count_operands (char *str)
+{
+ char *oper_end = str;
+ unsigned int oprnd_num;
+ int bracket_cnt = 0;
+
+ if (is_end_of_line[(unsigned char) *oper_end])
+ oprnd_num = 0;
+ else
+ oprnd_num = 1;
+
+ /* Count how many operands. */
+ if (oprnd_num)
+ while (!is_end_of_line[(unsigned char) *oper_end])
+ {
+ if (*oper_end == '(' || *oper_end == '<')
+ {
+ bracket_cnt++;
+ oper_end++;
+ continue;
+ }
+ if (*oper_end == ')' || *oper_end == '>')
+ {
+ bracket_cnt--;
+ oper_end++;
+ continue;
+ }
+ if (!bracket_cnt && *oper_end == ',')
+ oprnd_num++;
+ oper_end++;
+ }
+ return oprnd_num;
+}
+
+/* End of the operand parsing helper functions. */
+
+/* Parse the opcode part of an instruction. Fill in the csky_insn
+ state and return true on success, false otherwise. */
+
+static bfd_boolean
+parse_opcode (char *str)
+{
+#define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
+#define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
+
+ /* TRUE if this opcode has a suffix, like 'lrw.h'. */
+ unsigned int has_suffix = FALSE;
+ unsigned int nlen = 0;
+ char *opcode_end;
+ char name[OPCODE_MAX_LEN + 1];
+ char macro_name[OPCODE_MAX_LEN + 1];
+
+ /* Remove space ahead of string. */
+ while (ISSPACE (*str))
+ str++;
+ opcode_end = str;
+
+ /* Find the opcode end. */
+ while (nlen < OPCODE_MAX_LEN
+ && !is_end_of_line [(unsigned char) *opcode_end]
+ && *opcode_end != ' ')
+ {
+ /* Is csky force 32 or 16 instruction? */
+ if (IS_CSKY_V2 (mach_flag)
+ && *opcode_end == '.' && has_suffix == FALSE)
+ {
+ has_suffix = TRUE;
+ if (IS_OPCODE32F (opcode_end))
+ {
+ csky_insn.flag_force = INSN_OPCODE32F;
+ nlen -= 2;
+ }
+ else if (IS_OPCODE16F (opcode_end))
+ {
+ csky_insn.flag_force = INSN_OPCODE16F;
+ nlen -= 2;
+ }
+ }
+ name[nlen] = *opcode_end;
+ nlen++;
+ opcode_end++;
+ }
+
+ /* Is csky force 32 or 16 instruction? */
+ if (has_suffix == FALSE)
+ {
+ if (IS_CSKY_V2 (mach_flag) && IS_OPCODE32F (opcode_end))
+ {
+ csky_insn.flag_force = INSN_OPCODE32F;
+ nlen -= 2;
+ }
+ else if (IS_OPCODE16F (opcode_end))
+ {
+ csky_insn.flag_force = INSN_OPCODE16F;
+ nlen -= 2;
+ }
+ }
+ name[nlen] = '\0';
+
+ /* Generate macro_name for finding hash in macro hash_table. */
+ if (has_suffix == TRUE)
+ nlen += 2;
+ strncpy (macro_name, str, nlen);
+ macro_name[nlen] = '\0';
+
+ /* Get csky_insn.opcode_end. */
+ while (ISSPACE (*opcode_end))
+ opcode_end++;
+ csky_insn.opcode_end = opcode_end;
+
+ /* Count the operands. */
+ csky_insn.number = csky_count_operands (opcode_end);
+
+ /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
+ csky_insn.macro = (struct csky_macro_info *) hash_find (csky_macros_hash,
+ macro_name);
+ csky_insn.opcode = (struct csky_opcode *) hash_find (csky_opcodes_hash,
+ name);
+
+ if (csky_insn.macro == NULL && csky_insn.opcode == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+/* Main dispatch routine to parse operand OPRND for opcode OP from string
+ *OPER. */
+
+static bfd_boolean
+get_operand_value (struct csky_opcode_info *op,
+ char **oper, struct operand *oprnd)
+{
+ struct soperand *soprnd = NULL;
+ if (oprnd->mask == HAS_SUB_OPERAND)
+ {
+ /* It has sub operand, it must be like:
+ (oprnd1, oprnd2)
+ or
+ <oprnd1, oprnd2>
+ We will check the format here. */
+ soprnd = (struct soperand *) oprnd;
+ char lc = 0;
+ char rc = 0;
+ char *s = *oper;
+ int bracket_cnt = 0;
+ if (oprnd->type == OPRND_TYPE_BRACKET)
+ {
+ lc = '(';
+ rc = ')';
+ }
+ else if (oprnd->type == OPRND_TYPE_ABRACKET)
+ {
+ lc = '<';
+ rc = '>';
+ }
+
+ if (**oper == lc)
+ {
+ *oper += 1;
+ s += 1;
+ }
+ else
+ {
+ SET_ERROR_NUMBER ((oprnd->type == OPRND_TYPE_BRACKET
+ ? ERROR_MISSING_LBRACKET
+ : ERROR_MISSING_LANGLE_BRACKETS), NULL);
+ return FALSE;
+ }
+
+ /* If the oprnd2 is an immediate, it can not be parsed
+ that end with ')'/'>'. Modify ')'/'>' to '\0'. */
+ while ((*s != rc || bracket_cnt != 0) && (*s != '\n' && *s != '\0'))
+ {
+ if (*s == lc)
+ bracket_cnt++;
+ else if (*s == rc)
+ bracket_cnt--;
+ s++;
+ }
+
+ if (*s == rc)
+ *s = '\0';
+ else
+ {
+ SET_ERROR_NUMBER ((oprnd->type == OPRND_TYPE_BRACKET
+ ? ERROR_MISSING_RBRACKET
+ : ERROR_MISSING_RANGLE_BRACKETS), NULL);
+ return FALSE;
+ }
+
+ if (get_operand_value (op, oper, &soprnd->subs[0]) == FALSE)
+ {
+ *s = rc;
+ return FALSE;
+ }
+ if (**oper == ',')
+ *oper += 1;
+ if (get_operand_value (op, oper, &soprnd->subs[1]) == FALSE)
+ {
+ *s = rc;
+ return FALSE;
+ }
+
+ *s = rc;
+ *oper += 1;
+ return TRUE;
+ }
+
+ switch (oprnd->type)
+ {
+ /* TODO: add opcode type here, log errors in the function.
+ If REGLIST, then j = csky_insn.number - 1.
+ If there is needed to parse expressions, it will be
+ handled here. */
+ case OPRND_TYPE_CTRLREG:
+ /* some parse. */
+ return parse_type_ctrlreg (oper);
+ case OPRND_TYPE_AREG:
+ return parse_type_areg (oper);
+ case OPRND_TYPE_FREG:
+ case OPRND_TYPE_VREG:
+ return parse_type_freg (oper, 0);
+ case OPRND_TYPE_FEREG:
+ return parse_type_freg (oper, 1);
+ case OPRND_TYPE_CPCREG:
+ return parse_type_cpcreg (oper);
+ case OPRND_TYPE_CPREG:
+ return parse_type_cpreg (oper);
+ case OPRND_TYPE_CPIDX:
+ return parse_type_cpidx (oper);
+ case OPRND_TYPE_GREG0_7:
+ case OPRND_TYPE_GREG0_15:
+ {
+ int len;
+ long reg;
+ reg = csky_get_reg_val (*oper, &len);
+
+ if (reg == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL);
+ return FALSE;
+ }
+ else if ((oprnd->type == OPRND_TYPE_GREG0_7 && reg > 7)
+ || (oprnd->type == OPRND_TYPE_GREG0_15 && reg > 15))
+ {
+ SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
+ return FALSE;
+ }
+ *oper += len;
+ csky_insn.val[csky_insn.idx++] = reg;
+ return TRUE;
+ }
+ case OPRND_TYPE_REGnsplr:
+ {
+ int len;
+ long reg;
+ reg = csky_get_reg_val (*oper, &len);
+
+ if (reg == -1
+ || (IS_CSKY_V1 (mach_flag)
+ && (reg == V1_REG_SP || reg == V1_REG_LR)))
+ {
+ SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
+ return FALSE;
+ }
+ csky_insn.val[csky_insn.idx++] = reg;
+ *oper += len;
+ return TRUE;;
+ }
+ case OPRND_TYPE_REGnr4_r7:
+ {
+ int len;
+ int reg;
+ if (**oper == '(')
+ *oper += 1;
+ reg = csky_get_reg_val (*oper, &len);
+ if (reg == -1 || (reg <= 7 && reg >= 4))
+ return FALSE;
+
+ csky_insn.val[csky_insn.idx++] = reg;
+ *oper += len;
+
+ if (**oper == ')')
+ *oper += 1;
+ return TRUE;;
+ }
+ case OPRND_TYPE_REGr4_r7:
+ if (memcmp (*oper, "r4-r7", sizeof ("r4-r7") - 1) == 0)
+ {
+ *oper += sizeof ("r4-r7") - 1;
+ csky_insn.val[csky_insn.idx++] = 0;
+ return TRUE;
+ }
+ SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL, NULL);
+ return FALSE;
+ case OPRND_TYPE_IMM_LDST:
+ return parse_ldst_imm (oper, op, oprnd);
+ case OPRND_TYPE_IMM_FLDST:
+ return parse_ldst_imm (oper, op, oprnd);
+ case OPRND_TYPE_IMM1b:
+ return is_imm_over_range (oper, 0, 1, -1);
+ case OPRND_TYPE_IMM2b:
+ return is_imm_over_range (oper, 0, 3, -1);
+ case OPRND_TYPE_IMM2b_JMPIX:
+ /* ck802j support jmpix16, but not support jmpix32. */
+ if (IS_CSKY_ARCH_802 (mach_flag)
+ && (op->opcode & 0xffff0000) != 0)
+ {
+ SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL, NULL);
+ return FALSE;
+ }
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ if (csky_insn.e1.X_op == O_constant)
+ {
+ csky_insn.opcode_end = *oper;
+ if (csky_insn.e1.X_add_number & 0x7)
+ {
+ SET_ERROR_NUMBER (ERROR_JMPIX_OVER_RANGE, NULL);
+ return FALSE;
+ }
+ csky_insn.val[csky_insn.idx++]
+ = (csky_insn.e1.X_add_number >> 3) - 2;
+ }
+ return TRUE;
+ case OPRND_TYPE_IMM4b:
+ return is_imm_over_range (oper, 0, 15, -1);
+ break;
+ case OPRND_TYPE_IMM5b:
+ return is_imm_over_range (oper, 0, 31, -1);
+ /* This type for "bgeni" in csky v1 ISA. */
+ case OPRND_TYPE_IMM5b_7_31:
+ if (is_imm_over_range (oper, 0, 31, -1))
+ {
+ int val = csky_insn.val[csky_insn.idx - 1];
+ /* immediate values of 0 -> 6 translate to movi. */
+ if (val <= 6)
+ {
+ const char *name = "movi";
+ csky_insn.opcode = (struct csky_opcode *)
+ hash_find (csky_opcodes_hash, name);
+ csky_insn.val[csky_insn.idx - 1] = 1 << val;
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
+
+ case OPRND_TYPE_IMM5b_1_31:
+ return is_imm_over_range (oper, 1, 31, -1);
+ case OPRND_TYPE_IMM5b_POWER:
+ if (is_imm_over_range (oper, 1, ~(1 << 31), 1 << 31))
+ {
+ int log;
+ int val = csky_insn.val[csky_insn.idx - 1];
+ log = csky_log_2 (val);
+ csky_insn.val[csky_insn.idx - 1] = log;
+ return (log == -1 ? FALSE : TRUE);
+ }
+ else
+ return FALSE;
+
+ /* This type for "mgeni" in csky v1 ISA. */
+ case OPRND_TYPE_IMM5b_7_31_POWER:
+ if (is_imm_over_range (oper, 1, ~(1 << 31), 1 << 31))
+ {
+ int log;
+ int val = csky_insn.val[csky_insn.idx - 1];
+ log = csky_log_2 (val);
+ /* Immediate values of 0 -> 6 translate to movi. */
+ if (log <= 6)
+ {
+ const char *name = "movi";
+ csky_insn.opcode = (struct csky_opcode *)
+ hash_find (csky_opcodes_hash, name);
+ as_warn (_("translating mgeni to movi"));
+ }
+ else
+ csky_insn.val[csky_insn.idx - 1] = log;
+ return (log == -1 ? FALSE : TRUE);
+ }
+ else
+ return FALSE;
+
+ case OPRND_TYPE_IMM5b_RORI:
+ {
+ unsigned max_shift = IS_CSKY_V1 (mach_flag) ? 31 : 32;
+
+ if (is_imm_over_range (oper, 1, max_shift, -1))
+ {
+ int i = csky_insn.idx - 1;
+ csky_insn.val[i] = 32 - csky_insn.val[i];
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ case OPRND_TYPE_IMM5b_BMASKI:
+ /* For csky v1 bmask inst. */
+
+ if (!is_imm_over_range (oper, 8, 31, 0))
+ {
+ unsigned int mask_val = csky_insn.val[csky_insn.idx - 1];
+ if (mask_val > 0 && mask_val < 8)
+ {
+ const char *op_movi = "movi";
+ csky_insn.opcode = (struct csky_opcode *)
+ hash_find (csky_opcodes_hash, op_movi);
+ if (csky_insn.opcode == NULL)
+ return FALSE;
+ csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
+ return TRUE;
+ }
+ }
+ return TRUE;
+
+ case OPRND_TYPE_IMM8b_BMASKI:
+ /* For csky v2 bmask, which will transfer to 16bits movi. */
+ if (is_imm_over_range (oper, 1, 8, -1))
+ {
+ unsigned int mask_val = csky_insn.val[csky_insn.idx - 1];
+ csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
+ return TRUE;
+ }
+ return FALSE;
+ case OPRND_TYPE_OIMM4b:
+ return is_oimm_over_range (oper, 1, 16);
+ case OPRND_TYPE_OIMM5b:
+ return is_oimm_over_range (oper, 1, 32);
+ case OPRND_TYPE_OIMM5b_IDLY:
+ if (is_imm_over_range (oper, 0, 32, -1))
+ {
+ /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
+ unsigned long imm = csky_insn.val[csky_insn.idx - 1];
+ if (imm < 4)
+ {
+ csky_show_error (WARNING_IDLY, 0, (void *)imm, NULL);
+ imm = 3;
+ }
+ else imm--;
+ csky_insn.val[csky_insn.idx - 1] = imm;
+ return TRUE;
+ }
+ else
+ return FALSE;
+
+ /* For csky v2 bmask inst. */
+ case OPRND_TYPE_OIMM5b_BMASKI:
+ if (!is_oimm_over_range (oper, 17, 32))
+ {
+ int mask_val = csky_insn.val[csky_insn.idx - 1];
+ if (mask_val + 1 == 0)
+ return TRUE;
+ if (mask_val > 0 && mask_val < 16)
+ {
+ const char *op_movi = "movi";
+ csky_insn.opcode = (struct csky_opcode *)
+ hash_find (csky_opcodes_hash, op_movi);
+ if (csky_insn.opcode == NULL)
+ return FALSE;
+ csky_insn.val[csky_insn.idx - 1] = (1 << (mask_val + 1)) - 1;
+ return TRUE;
+ }
+ }
+ return TRUE;
+ case OPRND_TYPE_IMM7b:
+ return is_imm_over_range (oper, 0, 127, -1);
+ case OPRND_TYPE_IMM8b:
+ return is_imm_over_range (oper, 0, 255, -1);
+ case OPRND_TYPE_IMM12b:
+ return is_imm_over_range (oper, 0, 4095, -1);
+ case OPRND_TYPE_IMM15b:
+ return is_imm_over_range (oper, 0, 0xfffff, -1);
+ case OPRND_TYPE_IMM16b:
+ return is_imm_over_range (oper, 0, 65535, -1);
+ case OPRND_TYPE_OIMM16b:
+ return is_oimm_over_range (oper, 1, 65536);
+ case OPRND_TYPE_IMM32b:
+ {
+ expressionS e;
+ char *new_oper = parse_exp (*oper, &e);
+ if (e.X_op == O_constant)
+ {
+ *oper = new_oper;
+ csky_insn.val[csky_insn.idx++] = e.X_add_number;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ case OPRND_TYPE_IMM16b_MOVIH:
+ case OPRND_TYPE_IMM16b_ORI:
+ {
+ bfd_reloc_code_real_type r = BFD_RELOC_NONE;
+ int len;
+ char *curr = *oper;
+ char * save = input_line_pointer;
+ /* get the reloc type, and set "@GOTxxx" as ' ' */
+ while (**oper != '@' && **oper != '\0')
+ *oper += 1;
+ if (**oper != '\0')
+ {
+ input_line_pointer = *oper;
+ lex_got (&r, &len);
+ while (*(*oper + len + 1) != '\0')
+ {
+ **oper = *(*oper + len + 1);
+ *(*oper + len + 1) = '\0';
+ *oper += 1;
+ }
+ **oper = '\0';
+ }
+ input_line_pointer = save;
+ *oper = parse_exp (curr, &csky_insn.e1);
+ return TRUE;
+ }
+ case OPRND_TYPE_PSR_BITS_LIST:
+ {
+ int ret = TRUE;
+ if (csky_insn.number == 0)
+ ret = FALSE;
+ else
+ {
+ csky_insn.val[csky_insn.idx] = 0;
+ if (is_psr_bit (oper) != FALSE)
+ while (**oper == ',')
+ {
+ *oper += 1;
+ if (is_psr_bit (oper) == FALSE)
+ {
+ ret = FALSE;
+ break;
+ }
+ }
+ else
+ ret = FALSE;
+ if (ret == TRUE && IS_CSKY_V1 (mach_flag)
+ && csky_insn.val[csky_insn.idx] > 8)
+ ret = FALSE;
+ }
+ if (!ret)
+ SET_ERROR_NUMBER (ERROR_OPERANDS_ILLEGAL, csky_insn.opcode_end);
+ return ret;
+ }
+ case OPRND_TYPE_RM:
+ {
+ /* FPU round mode. */
+ static const char *round_mode[] =
+ {
+ "rm_nearest",
+ "rm_zero",
+ "rm_posinf",
+ "rm_neginf",
+ NULL
+ };
+ int i;
+ for (i = 0; round_mode[i]; i++)
+ if (strncasecmp (*oper, round_mode[i], strlen (round_mode[i])) == 0)
+ {
+ *oper += strlen (round_mode[i]);
+ csky_insn.val[csky_insn.idx++] = i;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ case OPRND_TYPE_REGLIST_COMMA:
+ case OPRND_TYPE_BRACKET:
+ /* TODO: using sub operand union. */
+ case OPRND_TYPE_ABRACKET:
+ /* TODO: using sub operand union. */
+ case OPRND_TYPE_REGLIST_DASH:
+ return is_reglist_legal (oper);
+ case OPRND_TYPE_FREGLIST_DASH:
+ return is_freglist_legal (oper);
+ case OPRND_TYPE_AREG_WITH_BRACKET:
+ {
+ int len;
+ int reg;
+ if (**oper != '(')
+ {
+ SET_ERROR_NUMBER (ERROR_MISSING_LBRACKET, NULL);
+ return FALSE;
+ }
+ *oper += 1;
+ reg = csky_get_reg_val (*oper, &len);
+ if (reg == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_EXP_GREG, NULL);
+ return FALSE;
+ }
+ *oper += len;
+ if (**oper != ')')
+ {
+ SET_ERROR_NUMBER (ERROR_MISSING_RBRACKET, NULL);
+ return FALSE;
+ }
+ *oper += 1;
+ csky_insn.val[csky_insn.idx++] = reg;
+ return TRUE;
+ }
+ case OPRND_TYPE_REGsp:
+ return is_reg_sp (oper);
+ case OPRND_TYPE_REGbsp:
+ return is_reg_sp_with_bracket (oper);
+ /* For jmpi. */
+ case OPRND_TYPE_OFF8b:
+ case OPRND_TYPE_OFF16b:
+ *oper = parse_rt (*oper, 1, &csky_insn.e1, -1);
+ csky_insn.val[csky_insn.idx++] = 0;
+ return TRUE;
+ case OPRND_TYPE_LABEL_WITH_BRACKET:
+ case OPRND_TYPE_CONSTANT:
+ case OPRND_TYPE_ELRW_CONSTANT:
+ if (**oper == '[')
+ csky_insn.val[csky_insn.idx++] = 0;
+ else
+ csky_insn.val[csky_insn.idx++] = NEED_OUTPUT_LITERAL;
+ *oper = parse_rt (*oper, 0, &csky_insn.e1, -1);
+ return TRUE;
+ case OPRND_TYPE_FCONSTANT:
+ *oper = parse_rtf (*oper, 0, &csky_insn.e1);
+ return TRUE;
+
+ case OPRND_TYPE_SFLOAT:
+ case OPRND_TYPE_DFLOAT:
+ /* For fmovis and fmovid, which accept a constant float with
+ a limited range. */
+ {
+ uint64_t dbnum;
+ int imm4, imm8;
+
+ *oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
+ if (csky_insn.e1.X_op == O_absent)
+ return FALSE;
+
+ /* Convert the representation from IEEE double to the 13-bit
+ encoding used internally for fmovis and fmovid. */
+ imm4 = 11 - (((dbnum & 0x7ff0000000000000ULL) >> 52) - 1023);
+ /* Check float range. */
+ if ((dbnum & 0x00000fffffffffffULL) || imm4 < 0 || imm4 > 15)
+ {
+ csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
+ return FALSE;
+ }
+ imm8 = (dbnum & 0x000ff00000000000ULL) >> 44;
+ csky_insn.e1.X_add_number
+ = (((imm8 & 0xf) << 4)
+ | ((imm8 & 0xf0) << 17)
+ | ((imm4 & 0xf) << 16)
+ | ((dbnum & 0x8000000000000000ULL) >> 43));
+ return TRUE;
+ }
+
+ /* For grs v2. */
+ case OPRND_TYPE_IMM_OFF18b:
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ return TRUE;
+
+ case OPRND_TYPE_BLOOP_OFF4b:
+ *oper = parse_exp (*oper, &csky_insn.e2);
+ if (csky_insn.e2.X_op == O_symbol)
+ {
+ csky_insn.opcode_end = *oper;
+ return TRUE;
+ }
+ else
+ return FALSE;
+
+ case OPRND_TYPE_BLOOP_OFF12b:
+ case OPRND_TYPE_OFF10b:
+ case OPRND_TYPE_OFF11b:
+ case OPRND_TYPE_OFF16b_LSL1:
+ case OPRND_TYPE_OFF26b:
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ if (csky_insn.e1.X_op == O_symbol)
+ {
+ csky_insn.opcode_end = *oper;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
+ case OPRND_TYPE_REG_r1a:
+ {
+ int reg = 0;
+ int len = 0;
+ reg = csky_get_reg_val (*oper, &len);
+ if (reg == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The first operand must be register r1.");
+ return FALSE;
+ }
+ if (reg != 1)
+ mov_r1_after = TRUE;
+ *oper += len;
+ csky_insn.opcode_end = *oper;
+ csky_insn.val[csky_insn.idx++] = reg;
+ return TRUE;
+ }
+ case OPRND_TYPE_REG_r1b:
+ {
+ int reg = 0;
+ int len = 0;
+ reg = csky_get_reg_val (*oper, &len);
+ if (reg == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The second operand must be register r1.");
+ return FALSE;
+ }
+ if (reg != 1)
+ {
+ unsigned int mov_insn = CSKYV1_INST_MOV_R1_RX;
+ mov_insn |= reg << 4;
+ mov_r1_before = TRUE;
+ csky_insn.output = frag_more (2);
+ dwarf2_emit_insn (0);
+ md_number_to_chars (csky_insn.output, mov_insn, 2);
+ }
+ *oper += len;
+ csky_insn.opcode_end = *oper;
+ csky_insn.val[csky_insn.idx++] = reg;
+ return TRUE;
+ }
+ case OPRND_TYPE_DUMMY_REG:
+ {
+ int reg = 0;
+ int len = 0;
+ reg = csky_get_reg_val (*oper, &len);
+ if (reg == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL);
+ return FALSE;
+ }
+ if (reg != csky_insn.val[0])
+ {
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The second register must be the same as the first.");
+ return FALSE;
+ }
+ *oper += len;
+ csky_insn.opcode_end = *oper;
+ csky_insn.val[csky_insn.idx++] = reg;
+ return TRUE;
+ }
+ case OPRND_TYPE_2IN1_DUMMY:
+ {
+ int reg = 0;
+ int len = 0;
+ int max = 0;
+ int min = 0;
+ reg = csky_get_reg_val (*oper, &len);
+ if (reg == -1)
+ {
+ SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL);
+ return FALSE;
+ }
+ /* dummy reg's real type should be same with first operand. */
+ if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_15)
+ max = 15;
+ else if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_7)
+ max = 7;
+ else
+ return FALSE;
+ if (reg < min || reg > max)
+ return FALSE;
+ csky_insn.val[csky_insn.idx++] = reg;
+ /* if it is the last operands. */
+ if (csky_insn.idx > 2)
+ {
+ /* For "insn rz, rx, ry", if rx or ry is equal to rz,
+ we can output the insn like "insn rz, rx". */
+ if (csky_insn.val[0] == csky_insn.val[1])
+ csky_insn.val[1] = 0;
+ else if (csky_insn.val[0] == csky_insn.val[2])
+ csky_insn.val[2] = 0;
+ else
+ return FALSE;
+ }
+ *oper += len;
+ csky_insn.opcode_end = *oper;
+ return TRUE;
+ }
+ case OPRND_TYPE_DUP_GREG0_7:
+ case OPRND_TYPE_DUP_GREG0_15:
+ case OPRND_TYPE_DUP_AREG:
+ {
+ long reg = 0;
+ int len = 0;
+ long max_reg;
+ unsigned int shift_num;
+ if (oprnd->type == OPRND_TYPE_DUP_GREG0_7)
+ {
+ max_reg = 7;
+ shift_num = 3;
+ }
+ else if (oprnd->type == OPRND_TYPE_DUP_GREG0_15)
+ {
+ max_reg = 15;
+ shift_num = 4;
+ }
+ else
+ {
+ max_reg = 31;
+ shift_num = 5;
+ }
+ reg = csky_get_reg_val (*oper, &len);
+ if (reg == -1)
+ {
+ if (max_reg == 31)
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The register must be r0-r31");
+ else
+ SET_ERROR_NUMBER (ERROR_REG_FORMAT,
+ "The register must be r0-r15");
+ return FALSE;
+ }
+ if (reg > max_reg)
+ {
+ SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
+ return FALSE;
+ }
+ reg |= reg << shift_num;
+ *oper += len;
+ csky_insn.opcode_end = *oper;
+ csky_insn.val[csky_insn.idx++] = reg;
+ return TRUE;
+ }
+ case OPRND_TYPE_CONST1:
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ if (csky_insn.e1.X_op == O_constant)
+ {
+ csky_insn.opcode_end = *oper;
+ if (csky_insn.e1.X_add_number != 1)
+ return FALSE;
+ csky_insn.val[csky_insn.idx++] = 1;
+ return TRUE;
+ }
+ return FALSE;
+ case OPRND_TYPE_UNCOND10b:
+ case OPRND_TYPE_UNCOND16b:
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ if (csky_insn.e1.X_op == O_constant)
+ return FALSE;
+ input_line_pointer = *oper;
+ csky_insn.opcode_end = *oper;
+ csky_insn.relax.max = UNCD_DISP16_LEN;
+ csky_insn.relax.var = UNCD_DISP10_LEN;
+ csky_insn.relax.subtype = UNCD_DISP10;
+ csky_insn.val[csky_insn.idx++] = 0;
+ return TRUE;
+ case OPRND_TYPE_COND10b:
+ case OPRND_TYPE_COND16b:
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ if (csky_insn.e1.X_op == O_constant)
+ return FALSE;
+ input_line_pointer = *oper;
+ csky_insn.opcode_end = *oper;
+ /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
+ jump around a 32-bit unconditional branch instead. */
+ if (IS_CSKY_ARCH_801 (mach_flag))
+ {
+ csky_insn.relax.max = SCOND_DISP16_LEN;
+ csky_insn.relax.var = SCOND_DISP10_LEN;
+ csky_insn.relax.subtype = SCOND_DISP10;
+ }
+ else
+ {
+ csky_insn.relax.max = COND_DISP16_LEN;
+ csky_insn.relax.var = COND_DISP10_LEN;
+ csky_insn.relax.subtype = COND_DISP10;
+ }
+ csky_insn.val[csky_insn.idx++] = 0;
+ return TRUE;
+ case OPRND_TYPE_JCOMPZ:
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ if (csky_insn.e1.X_op == O_constant)
+ return FALSE;
+ input_line_pointer = *oper;
+ csky_insn.opcode_end = *oper;
+ csky_insn.relax.max = JCOMPZ_DISP32_LEN;
+ csky_insn.relax.var = JCOMPZ_DISP16_LEN;
+ csky_insn.relax.subtype = JCOMPZ_DISP16;
+ csky_insn.max = JCOMPZ_DISP32_LEN;
+ csky_insn.val[csky_insn.idx++] = 0;
+ return TRUE;
+ case OPRND_TYPE_JBTF:
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ input_line_pointer = *oper;
+ csky_insn.opcode_end = *oper;
+ csky_insn.relax.max = csky_relax_table[C (COND_JUMP_S, DISP32)].rlx_length;
+ csky_insn.relax.var = csky_relax_table[C (COND_JUMP_S, DISP12)].rlx_length;
+ csky_insn.relax.subtype = C (COND_JUMP_S, 0);
+ csky_insn.val[csky_insn.idx++] = 0;
+ csky_insn.max = C32_LEN_S + 2;
+ return TRUE;
+ case OPRND_TYPE_JBR:
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ input_line_pointer = *oper;
+ csky_insn.opcode_end = *oper;
+ csky_insn.relax.max = csky_relax_table[C (UNCD_JUMP_S, DISP32)].rlx_length;
+ csky_insn.relax.var = csky_relax_table[C (UNCD_JUMP_S, DISP12)].rlx_length;
+ csky_insn.relax.subtype = C (UNCD_JUMP_S, 0);
+ csky_insn.val[csky_insn.idx++] = 0;
+ csky_insn.max = U32_LEN_S + 2;
+ return TRUE;
+ case OPRND_TYPE_JBSR:
+ if (do_force2bsr)
+ *oper = parse_exp (*oper, &csky_insn.e1);
+ else
+ *oper = parse_rt (*oper, 1, &csky_insn.e1, -1);
+ input_line_pointer = *oper;
+ csky_insn.opcode_end = *oper;
+ csky_insn.val[csky_insn.idx++] = 0;
+ return TRUE;
+ case OPRND_TYPE_REGLIST_DASH_COMMA:
+ return is_reglist_dash_comma_legal (oper, oprnd);
+
+ case OPRND_TYPE_MSB2SIZE:
+ case OPRND_TYPE_LSB2SIZE:
+ {
+ expressionS e;
+ char *new_oper = parse_exp (*oper, &e);
+ if (e.X_op == O_constant)
+ {
+ *oper = new_oper;
+ if (e.X_add_number > 31)
+ {
+ SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
+ return FALSE;
+ }
+ csky_insn.val[csky_insn.idx++] = e.X_add_number;
+ if (oprnd->type == OPRND_TYPE_LSB2SIZE)
+ {
+ if (csky_insn.val[csky_insn.idx - 1] > csky_insn.val[csky_insn.idx - 2])
+ {
+ SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
+ return FALSE;
+ }
+ csky_insn.val[csky_insn.idx - 2] -= e.X_add_number;
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+ case OPRND_TYPE_AREG_WITH_LSHIFT:
+ return is_reg_lshift_illegal (oper, 0);
+ case OPRND_TYPE_AREG_WITH_LSHIFT_FPU:
+ return is_reg_lshift_illegal (oper, 1);
+ case OPRND_TYPE_FREG_WITH_INDEX:
+ if (parse_type_freg (oper, 0))
+ {
+ if (**oper == '[')
+ {
+ (*oper)++;
+ if (is_imm_over_range (oper, 0, 0xf, -1))
+ {
+ if (**oper == ']')
+ {
+ unsigned int idx = --csky_insn.idx;
+ unsigned int val = csky_insn.val[idx];
+ (*oper)++;
+ csky_insn.val[idx - 1] |= val << 4;
+ return TRUE;
+ }
+ else
+ SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
+ }
+ }
+ else
+ SET_ERROR_NUMBER (ERROR_MISSING_LSQUARE_BRACKETS, NULL);
+ }
+ return FALSE;
+
+ default:
+ break;
+ /* error code. */
+ }
+ return FALSE;
+}
+
+/* Subroutine of parse_operands. */
+
+static bfd_boolean
+parse_operands_op (char *str, struct csky_opcode_info *op)
+{
+ int i;
+ int j;
+ char *oper = str;
+ int flag_pass;
+
+ for (i = 0; i < OP_TABLE_NUM && op[i].operand_num != -2; i++)
+ {
+ flag_pass = TRUE;
+ csky_insn.idx = 0;
+ oper = str;
+ /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
+ if (!(op[i].operand_num == csky_insn.number
+ || (op[i].operand_num == -1 && csky_insn.number != 0)))
+ {
+ /* The smaller err_num is more serious. */
+ SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER, op[i].operand_num);
+ flag_pass = FALSE;
+ continue;
+ }
+
+ for (j = 0; j < csky_insn.number; j++)
+ {
+ while (ISSPACE (*oper))
+ oper++;
+ flag_pass = get_operand_value (&op[i], &oper,
+ &op[i].oprnd.oprnds[j]);
+ if (flag_pass == FALSE)
+ break;
+ while (ISSPACE (*oper))
+ oper++;
+ /* Skip the ','. */
+ if (j < csky_insn.number - 1 && op[i].operand_num != -1)
+ {
+ if (*oper == ',')
+ oper++;
+ else
+ {
+ SET_ERROR_NUMBER (ERROR_MISSING_COMMA, NULL);
+ flag_pass = FALSE;
+ break;
+ }
+ }
+ else if (!is_end_of_line[(unsigned char) *oper])
+ {
+ SET_ERROR_NUMBER (ERROR_BAD_END, NULL);
+ flag_pass = FALSE;
+ break;
+ }
+ else
+ break;
+ }
+ /* Parse operands in one table end. */
+
+ if (flag_pass == TRUE)
+ {
+ /* Parse operands success, set opcode_idx. */
+ csky_insn.opcode_idx = i;
+ return TRUE;
+ }
+ else
+ error_state.opnum = j + 1;
+ }
+ /* Parse operands in ALL tables end. */
+ return FALSE;
+}
+
+/* Parse the operands according to operand type. */
+
+static bfd_boolean
+parse_operands (char *str)
+{
+ char *oper = str;
+
+ /* Parse operands according to flag_force. */
+ if (csky_insn.flag_force == INSN_OPCODE16F
+ && (csky_insn.opcode->isa_flag16 & isa_flag) != 0)
+ {
+ if (parse_operands_op (oper, csky_insn.opcode->op16) == TRUE)
+ {
+ csky_insn.isize = 2;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ else if (csky_insn.flag_force == INSN_OPCODE32F
+ && (csky_insn.opcode->isa_flag32 & isa_flag) != 0)
+ {
+ if (parse_operands_op (oper, csky_insn.opcode->op32) == TRUE)
+ {
+ csky_insn.isize = 4;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ else
+ {
+ if ((csky_insn.opcode->isa_flag16 & isa_flag) != 0
+ && parse_operands_op (oper, csky_insn.opcode->op16) == TRUE)
+ {
+ csky_insn.isize = 2;
+ return TRUE;
+ }
+ if ((csky_insn.opcode->isa_flag32 & isa_flag) != 0
+ && parse_operands_op (oper, csky_insn.opcode->op32) == TRUE)
+ {
+ csky_insn.isize = 4;
+ return TRUE;
+ }
+ return FALSE;
+ }
+}
+
+static bfd_boolean
+csky_generate_frags (void)
+{
+ /* frag more relax reloc. */
+ if (csky_insn.flag_force == INSN_OPCODE16F
+ || !IS_SUPPORT_OPCODE32 (csky_insn.opcode))
+ {
+ csky_insn.output = frag_more (csky_insn.isize);
+ if (csky_insn.opcode->reloc16)
+ {
+ /* 16 bits opcode force, should generate fixup. */
+ reloc_howto_type *howto;
+ howto = bfd_reloc_type_lookup (stdoutput,
+ csky_insn.opcode->reloc16);
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 2, &csky_insn.e1, howto->pc_relative,
+ csky_insn.opcode->reloc16);
+ }
+ }
+ else if (csky_insn.flag_force == INSN_OPCODE32F)
+ {
+ csky_insn.output = frag_more (csky_insn.isize);
+ if (csky_insn.opcode->reloc32)
+ {
+ reloc_howto_type *howto;
+ howto = bfd_reloc_type_lookup (stdoutput,
+ csky_insn.opcode->reloc32);
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, howto->pc_relative,
+ csky_insn.opcode->reloc32);
+ }
+ }
+ else if (csky_insn.opcode->relax)
+ /* Generate the relax information. */
+ csky_insn.output = frag_var (rs_machine_dependent,
+ csky_insn.relax.max,
+ csky_insn.relax.var,
+ csky_insn.relax.subtype,
+ csky_insn.e1.X_add_symbol,
+ csky_insn.e1.X_add_number, 0);
+ else
+ {
+ csky_insn.output = frag_more (csky_insn.isize);
+ if (csky_insn.opcode->reloc16 && csky_insn.isize == 2)
+ {
+ reloc_howto_type *howto;
+ howto = bfd_reloc_type_lookup (stdoutput,
+ csky_insn.opcode->reloc16);
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 2, &csky_insn.e1, howto->pc_relative,
+ csky_insn.opcode->reloc16);
+ }
+ else if (csky_insn.opcode->reloc32 && csky_insn.isize == 4)
+ {
+ reloc_howto_type *howto;
+ howto = bfd_reloc_type_lookup (stdoutput,
+ csky_insn.opcode->reloc32);
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, howto->pc_relative,
+ csky_insn.opcode->reloc32);
+ }
+ }
+ return TRUE;
+}
+
+/* Return the bits of VAL shifted according to MASK. The bits of MASK
+ need not be contiguous. */
+
+static int
+generate_masked_value (int mask, int val)
+{
+ int ret = 0;
+ int bit;
+
+ for (bit = 1; mask; bit = bit << 1)
+ if (mask & bit)
+ {
+ if (val & 0x1)
+ ret |= bit;
+ val = val >> 1;
+ mask &= ~bit;
+ }
+ return ret;
+}
+
+/* Return the result of masking operand number OPRND_IDX into the
+ instruction word according to the information in OPRND. */
+
+static int
+generate_masked_operand (struct operand *oprnd, int *oprnd_idx)
+{
+ struct soperand *soprnd = NULL;
+ int mask;
+ int val;
+ if ((unsigned int)oprnd->mask == HAS_SUB_OPERAND)
+ {
+ soprnd = (struct soperand *) oprnd;
+ generate_masked_operand (&soprnd->subs[0], oprnd_idx);
+ generate_masked_operand (&soprnd->subs[1], oprnd_idx);
+ return 0;
+ }
+ mask = oprnd->mask;
+ val = csky_insn.val[*oprnd_idx];
+ (*oprnd_idx)++;
+ val = generate_masked_value (mask, val);
+ csky_insn.inst |= val;
+
+ return 0;
+}
+
+static bfd_boolean
+csky_generate_insn (void)
+{
+ int i = 0;
+ struct csky_opcode_info *opinfo = NULL;
+
+ if (csky_insn.isize == 4)
+ opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
+ else if (csky_insn.isize == 2)
+ opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
+
+ int sidx = 0;
+ csky_insn.inst = opinfo->opcode;
+ if (opinfo->operand_num == -1)
+ {
+ generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
+ return 0;
+ }
+ else
+ for (i = 0; i < opinfo->operand_num; i++)
+ generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
+ return 0;
+}
+
+/* Main entry point for assembling a single instruction. */
+
+void
+md_assemble (char *str)
+{
+ bfd_boolean must_check_literals = TRUE;
+ csky_insn.isize = 0;
+ csky_insn.idx = 0;
+ csky_insn.max = 0;
+ csky_insn.flag_force = INSN_OPCODE;
+ csky_insn.macro = NULL;
+ csky_insn.opcode = NULL;
+ memset (csky_insn.val, 0, sizeof (int) * MAX_OPRND_NUM);
+ /* Initialize err_num. */
+ error_state.err_num = ERROR_NONE;
+ mov_r1_before = FALSE;
+ mov_r1_after = FALSE;
+
+ mapping_state (MAP_TEXT);
+ /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
+ dwarf2_emit_insn (0);
+ while (ISSPACE (* str))
+ str++;
+ /* Get opcode from str. */
+ if (parse_opcode (str) == FALSE)
+ {
+ csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
+ return;
+ }
+
+ /* If it is a macro instruction, handle it. */
+ if (csky_insn.macro != NULL)
+ {
+ if (csky_insn.number == csky_insn.macro->oprnd_num)
+ {
+ csky_insn.macro->handle_func ();
+ return;
+ }
+ else if (error_state.err_num > ERROR_OPERANDS_NUMBER)
+ SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER, csky_insn.macro->oprnd_num);
+ }
+
+ if (csky_insn.opcode == NULL)
+ {
+ SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL, NULL);
+ csky_show_error (error_state.err_num, error_state.opnum,
+ (void *)error_state.arg1, (void *)error_state.arg1);
+ return;
+ }
+
+ /* Parse the operands according to operand type. */
+ if (parse_operands (csky_insn.opcode_end) == FALSE)
+ {
+ csky_show_error (error_state.err_num, error_state.opnum,
+ (void *)error_state.arg1, (void *)error_state.arg1);
+ return;
+ }
+
+ /* if this insn has work in opcode table, then do it. */
+ if (csky_insn.opcode->work != NULL)
+ must_check_literals = csky_insn.opcode->work ();
+ else
+ {
+ /* Generate relax or reloc if necessary. */
+ csky_generate_frags ();
+ /* Generate the insn by mask. */
+ csky_generate_insn ();
+ /* Write inst to frag. */
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ }
+
+ /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
+ if (mov_r1_after == TRUE)
+ {
+ unsigned int mov_insn = CSKYV1_INST_MOV_RX_R1;
+ mov_insn |= csky_insn.val[0];
+ mov_r1_before = TRUE;
+ csky_insn.output = frag_more (2);
+ dwarf2_emit_insn (0);
+ md_number_to_chars (csky_insn.output, mov_insn, 2);
+ csky_insn.isize += 2;
+ }
+ if (mov_r1_before == TRUE)
+ csky_insn.isize += 2;
+
+ /* Check literal. */
+ if (must_check_literals)
+ {
+ if (csky_insn.max == 0)
+ check_literals (csky_insn.opcode->transfer, csky_insn.isize);
+ else
+ check_literals (csky_insn.opcode->transfer, csky_insn.max);
+ }
+
+ insn_reloc = BFD_RELOC_NONE;
+}
+
+/* Attempt to handle option with value C, returning non-zero on success. */
+
+int
+md_parse_option (int c, const char *arg)
+{
+ switch (c)
+ {
+ case 0:
+ break;
+ case OPTION_MARCH:
+ parse_arch (arg);
+ break;
+ case OPTION_MCPU:
+ parse_cpu (arg);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/* Convert a machine dependent frag. */
+#define PAD_LITERAL_LENGTH 6
+#define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
+#define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
+#define make_insn(total_length, opcode, operand, operand_length) \
+ do { \
+ if (total_length > 0) \
+ { \
+ csky_write_insn (buf, \
+ opcode | (operand & ((1 << operand_length) - 1)), \
+ total_length); \
+ buf += total_length; \
+ fragp->fr_fix += total_length; \
+ } \
+ } while (0)
+
+#define make_literal(fragp, literal_offset) \
+ do { \
+ make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
+ fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
+ fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
+ make_insn (4, 0, 0, 0); \
+ make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
+ } while (0)
+
+void
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
+{
+ offsetT disp;
+ char *buf = fragp->fr_fix + fragp->fr_literal;
+
+ gas_assert (fragp->fr_symbol);
+ if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
+ disp = 0;
+ else
+ disp = (S_GET_VALUE (fragp->fr_symbol)
+ + fragp->fr_offset
+ - fragp->fr_address
+ - fragp->fr_fix);
+
+ switch (fragp->fr_subtype)
+ {
+ /* generate new insn. */
+ case C (COND_JUMP, DISP12):
+ case C (UNCD_JUMP, DISP12):
+ case C (COND_JUMP_PIC, DISP12):
+ case C (UNCD_JUMP_PIC, DISP12):
+ {
+#define CSKY_V1_B_MASK 0xf8
+ unsigned char t0;
+ disp -= 2;
+ if (disp & 1)
+ {
+ /* Error. odd displacement at %x, next_inst-2. */
+ ;
+ }
+ disp >>= 1;
+
+ if (!target_big_endian)
+ {
+ t0 = buf[1] & CSKY_V1_B_MASK;
+ md_number_to_chars (buf, disp, 2);
+ buf[1] = (buf[1] & ~CSKY_V1_B_MASK) | t0;
+ }
+ else
+ {
+ t0 = buf[0] & CSKY_V1_B_MASK;
+ md_number_to_chars (buf, disp, 2);
+ buf[0] = (buf[0] & ~CSKY_V1_B_MASK) | t0;
+ }
+ fragp->fr_fix += 2;
+ break;
+ }
+ case C (COND_JUMP, DISP32):
+ case C (COND_JUMP, UNDEF_WORD_DISP):
+ {
+ /* A conditional branch wont fit into 12 bits:
+ b!cond 1f
+ jmpi 0f
+ .align 2
+ 0: .long disp
+ 1:
+ */
+ int first_inst = fragp->fr_fix + fragp->fr_address;
+ int is_unaligned = (first_inst & 3);
+
+ if (!target_big_endian)
+ {
+ /* b!cond instruction. */
+ buf[1] ^= 0x08;
+ /* jmpi instruction. */
+ buf[2] = CSKYV1_INST_JMPI & 0xff;
+ buf[3] = CSKYV1_INST_JMPI >> 8;
+ }
+ else
+ {
+ /* b!cond instruction. */
+ buf[0] ^= 0x08;
+ /* jmpi instruction. */
+ buf[2] = CSKYV1_INST_JMPI >> 8;
+ buf[3] = CSKYV1_INST_JMPI & 0xff;
+ }
+
+ if (is_unaligned)
+ {
+ if (!target_big_endian)
+ {
+ /* bt/bf: jump to pc + 2 + (4 << 1). */
+ buf[0] = 4;
+ /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
+ buf[2] = 1;
+ }
+ else
+ {
+ /* bt/bf: jump to pc + 2 + (4 << 1). */
+ buf[1] = 4;
+ /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
+ buf[3] = 1;
+ }
+ /* Aligned 4 bytes. */
+ buf[4] = 0;
+ buf[5] = 0;
+ /* .long */
+ buf[6] = 0;
+ buf[7] = 0;
+ buf[8] = 0;
+ buf[9] = 0;
+
+ /* Make reloc for the long disp. */
+ fix_new (fragp, fragp->fr_fix + 6, 4,
+ fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
+ fragp->fr_fix += C32_LEN;
+ }
+ else
+ {
+ if (!target_big_endian)
+ {
+ /* bt/bf: jump to pc + 2 + (3 << 1). */
+ buf[0] = 3;
+ /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
+ buf[2] = 0;
+ }
+ else
+ {
+ /* bt/bf: jump to pc + 2 + (3 << 1). */
+ buf[1] = 3;
+ /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
+ buf[3] = 0;
+ }
+ /* .long */
+ buf[4] = 0;
+ buf[5] = 0;
+ buf[6] = 0;
+ buf[7] = 0;
+
+ /* Make reloc for the long disp. */
+ fix_new (fragp, fragp->fr_fix + 4, 4,
+ fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
+ fragp->fr_fix += C32_LEN;
+
+ /* Frag is actually shorter (see the other side of this ifdef)
+ but gas isn't prepared for that. We have to re-adjust
+ the branch displacement so that it goes beyond the
+ full length of the fragment, not just what we actually
+ filled in. */
+ if (!target_big_endian)
+ buf[0] = 4;
+ else
+ buf[1] = 4;
+ }
+ }
+ break;
+
+ case C (COND_JUMP_PIC, DISP32):
+ case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
+ {
+#define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
+#define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
+ /* b!cond 1f
+ subi sp, 8
+ stw r15, (sp, 0)
+ bsr .L0
+ .L0:
+ lrw r1, 0f
+ add r1, r15
+ addi sp, 8
+ jmp r1
+ .align 2
+ 0: .long (tar_addr - pc)
+ 1:
+ */
+ int first_inst = fragp->fr_fix + fragp->fr_address;
+ int is_unaligned = (first_inst & 3);
+ disp -= 8;
+ /* Toggle T/F bit. */
+ if (! target_big_endian)
+ buf[1] ^= 0x08;
+ else
+ buf[0] ^= 0x08;
+ buf[2] = BYTE_0 (CSKYV1_INST_SUBI | (7 << 4)); /* subi r0, 8. */
+ buf[3] = BYTE_1 (CSKYV1_INST_SUBI | (7 << 4));
+ buf[4] = BYTE_0 (CSKYV1_INST_STW | (15 << 8)); /* stw r15, r0. */
+ buf[5] = BYTE_1 (CSKYV1_INST_STW | (15 << 8));
+ buf[6] = BYTE_0 (CSKYV1_INST_BSR); /* bsr pc + 2. */
+ buf[7] = BYTE_1 (CSKYV1_INST_BSR);
+ buf[8] = BYTE_0 (CSKYV1_INST_LRW | (1 << 8)); /* lrw r1, (tar_addr - pc). */
+ buf[9] = BYTE_1 (CSKYV1_INST_LRW | (1 << 8));
+ buf[10] = BYTE_0 (CSKYV1_INST_ADDU | (15 << 4) | 1); /* add r1, r15. */
+ buf[11] = BYTE_1 (CSKYV1_INST_ADDU | (15 << 4) | 1);
+ buf[12] = BYTE_0 (CSKYV1_INST_LDW | (15 << 8)); /* ldw r15, r0. */
+ buf[13] = BYTE_1 (CSKYV1_INST_LDW | (15 << 8));
+ buf[14] = BYTE_0 (CSKYV1_INST_ADDI | (7 << 4)); /* addi r0, 8. */
+ buf[15] = BYTE_1 (CSKYV1_INST_ADDI | (7 << 4));
+ buf[16] = BYTE_0 (CSKYV1_INST_JMP | 1); /* jmp r1. */
+ buf[17] = BYTE_1 (CSKYV1_INST_JMP | 1);
+
+ if (!is_unaligned)
+ {
+ if (!target_big_endian)
+ {
+ buf[0] = 11;
+ buf[8] = 3;
+ buf[20] = disp & 0xff;
+ buf[21] = (disp >> 8) & 0xff;
+ buf[22] = (disp >> 16) & 0xff;
+ buf[23] = (disp >> 24) & 0xff;
+ }
+ else /* if !target_big_endian. */
+ {
+ buf[1] = 11;
+ buf[9] = 3;
+ buf[20] = (disp >> 24) & 0xff;
+ buf[21] = (disp >> 16) & 0xff;
+ buf[22] = (disp >> 8) & 0xff;
+ buf[23] = disp & 0xff;
+ }
+ buf[18] = 0; /* alignment. */
+ buf[19] = 0;
+ fragp->fr_fix += C32_LEN_PIC;
+ }
+ else /* if !is_unaligned. */
+ {
+ if (!target_big_endian)
+ {
+ buf[0] = 11;
+ buf[8] = 2;
+ buf[18] = disp & 0xff;
+ buf[19] = (disp >> 8) & 0xff;
+ buf[20] = (disp >> 16) & 0xff;
+ buf[21] = (disp >> 24) & 0xff;
+ }
+ else /* if !target_big_endian. */
+ {
+ buf[1] = 11;
+ buf[9] = 2;
+ buf[18] = (disp >> 24) & 0xff;
+ buf[19] = (disp >> 16) & 0xff;
+ buf[20] = (disp >> 8) & 0xff;
+ buf[21] = disp & 0xff;
+ }
+ fragp->fr_fix += C32_LEN_PIC;
+
+ } /* end if is_unaligned. */
+ } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
+ break;
+ case C (UNCD_JUMP, DISP32):
+ case C (UNCD_JUMP, UNDEF_WORD_DISP):
+ {
+ /* jmpi 0f
+ .align 2
+ 0: .long disp. */
+ int first_inst = fragp->fr_fix + fragp->fr_address;
+ int is_unaligned = (first_inst & 3);
+ /* Build jmpi. */
+ buf[0] = BYTE_0 (CSKYV1_INST_JMPI);
+ buf[1] = BYTE_1 (CSKYV1_INST_JMPI);
+ if (!is_unaligned)
+ {
+ if (!target_big_endian)
+ buf[0] = 1;
+ else
+ buf[1] = 1;
+ /* Alignment. */
+ buf[2] = 0;
+ buf[3] = 0;
+ /* .long */
+ buf[4] = 0;
+ buf[5] = 0;
+ buf[6] = 0;
+ buf[7] = 0;
+ fix_new (fragp, fragp->fr_fix + 4, 4,
+ fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
+ fragp->fr_fix += U32_LEN;
+ }
+ else /* if is_unaligned. */
+ {
+ if (!target_big_endian)
+ buf[0] = 0;
+ else
+ buf[1] = 0;
+ /* .long */
+ buf[2] = 0;
+ buf[3] = 0;
+ buf[4] = 0;
+ buf[5] = 0;
+ fix_new (fragp, fragp->fr_fix + 2, 4,
+ fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
+ fragp->fr_fix += U32_LEN;
+
+ }
+ }
+ break;
+ case C (UNCD_JUMP_PIC, DISP32):
+ case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
+ {
+ /* subi sp, 8
+ stw r15, (sp)
+ bsr .L0
+ .L0:
+ lrw r1, 0f
+ add r1, r15
+ ldw r15, (sp)
+ addi sp, 8
+ jmp r1
+ .align 2
+ 0: .long (tar_add - pc)
+ 1:
+ */
+ /* If the b!cond is 4 byte aligned, the literal which would
+ go at x+4 will also be aligned. */
+ int first_inst = fragp->fr_fix + fragp->fr_address;
+ int is_unaligned = (first_inst & 3);
+ disp -= 6;
+
+ buf[0] = BYTE_0 (CSKYV1_INST_SUBI | (7 << 4)); /* subi r0, 8. */
+ buf[1] = BYTE_1 (CSKYV1_INST_SUBI | (7 << 4));
+ buf[2] = BYTE_0 (CSKYV1_INST_STW | (15 << 8)); /* stw r15, r0. */
+ buf[3] = BYTE_1 (CSKYV1_INST_STW | (15 << 8));
+ buf[4] = BYTE_0 (CSKYV1_INST_BSR); /* bsr pc + 2. */
+ buf[5] = BYTE_1 (CSKYV1_INST_BSR);
+ buf[6] = BYTE_0 (CSKYV1_INST_LRW | (1 << 8)); /* lrw r1, (tar_addr - pc). */
+ buf[7] = BYTE_1 (CSKYV1_INST_LRW | (1 << 8));
+ buf[8] = BYTE_0 (CSKYV1_INST_ADDU | (15 << 4) | 1); /* add r1, r15. */
+ buf[9] = BYTE_1 (CSKYV1_INST_ADDU | (15 << 4) | 1);
+ buf[10] = BYTE_0 (CSKYV1_INST_LDW | (15 << 8)); /* ldw r15, r0. */
+ buf[11] = BYTE_1 (CSKYV1_INST_LDW | (15 << 8));
+ buf[12] = BYTE_0 (CSKYV1_INST_ADDI | (7 << 4)); /* addi r0, 8. */
+ buf[13] = BYTE_1 (CSKYV1_INST_ADDI | (7 << 4));
+ buf[14] = BYTE_0 (CSKYV1_INST_JMP | 1); /* jmp r1. */
+ buf[15] = BYTE_1 (CSKYV1_INST_JMP | 1);
+
+ if (is_unaligned)
+ {
+ if (!target_big_endian)
+ {
+ buf[6] = 3;
+ buf[18] = disp & 0xff;
+ buf[19] = (disp >> 8) & 0xff;
+ buf[20] = (disp >> 16) & 0xff;
+ buf[21] = (disp >> 24) & 0xff;
+ }
+ else
+ {
+ buf[7] = 3;
+ buf[18] = (disp >> 24) & 0xff;
+ buf[19] = (disp >> 16) & 0xff;
+ buf[20] = (disp >> 8) & 0xff;
+ buf[21] = disp & 0xff;
+ }
+ buf[16] = 0;
+ buf[17] = 0;
+ fragp->fr_fix += U32_LEN_PIC;
+ }
+ else
+ {
+ if (!target_big_endian)
+ {
+ buf[6] = 2;
+ buf[16] = disp & 0xff;
+ buf[17] = (disp >> 8) & 0xff;
+ buf[18] = (disp >> 16) & 0xff;
+ buf[19] = (disp >> 24) & 0xff;
+ }
+ else
+ {
+ buf[7] = 2;
+ buf[16] = (disp >> 24) & 0xff;
+ buf[17] = (disp >> 16) & 0xff;
+ buf[18] = (disp >> 8) & 0xff;
+ buf[19] = disp & 0xff;
+ }
+ fragp->fr_fix += U32_LEN_PIC;
+ }
+ }
+ break;
+ case COND_DISP10:
+ case SCOND_DISP10:
+ case UNCD_DISP10:
+ case JCOND_DISP10:
+ case JUNCD_DISP10:
+ {
+ unsigned int inst = csky_read_insn (buf, 2);
+ inst |= (disp >> 1) & ((1 << 10) - 1);
+ csky_write_insn (buf, inst, 2);
+ fragp->fr_fix += 2;
+ break;
+ }
+ case SCOND_DISP16:
+ {
+ unsigned int inst = csky_read_insn (buf, 2);
+
+ if (inst == CSKYV2_INST_BT16)
+ inst = CSKYV2_INST_BF16;
+ else
+ inst = CSKYV2_INST_BT16;
+ make_insn (2, inst, (2 + 4) >> 1, 10);
+ if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
+ fix_new (fragp, fragp->fr_fix, 4,
+ fragp->fr_symbol, fragp->fr_offset, 1,
+ BFD_RELOC_CKCORE_PCREL_IMM16BY2);
+ disp -= 2;
+ inst = CSKYV2_INST_BR32 | ((disp >> 1) & ((1 << 16) - 1));
+ csky_write_insn (buf, inst, 4);
+ fragp->fr_fix += 4;
+ break;
+ }
+ case COND_DISP16:
+ case JCOND_DISP16:
+ {
+ unsigned int inst = csky_read_insn (buf, 2);
+
+ if (inst == CSKYV2_INST_BT16)
+ inst = CSKYV2_INST_BT32;
+ else
+ inst = CSKYV2_INST_BF32;
+ if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
+ fix_new (fragp, fragp->fr_fix, 4,
+ fragp->fr_symbol, fragp->fr_offset, 1,
+ BFD_RELOC_CKCORE_PCREL_IMM16BY2);
+ inst |= (disp >> 1) & ((1 << 16) - 1);
+ csky_write_insn (buf, inst, 4);
+ fragp->fr_fix += 4;
+ break;
+ }
+ case LRW_DISP7:
+ {
+ unsigned int inst = csky_read_insn (buf, 2);
+ int imm;
+ imm = (disp + 2) >> 2;
+ inst |= (imm >> 5) << 8;
+ make_insn (2, inst, (imm & 0x1f), 5);
+ break;
+ }
+ case LRW2_DISP8:
+ {
+ unsigned int inst = csky_read_insn (buf, 2);
+ int imm = (disp + 2) >> 2;
+ if (imm >= 0x80)
+ {
+ inst &= 0xe0;
+ inst |= (~((imm >> 5) << 8)) & 0x300;
+ make_insn (2, inst, (~imm & 0x1f), 5);
+ }
+ else
+ {
+ inst |= (imm >> 5) << 8;
+ make_insn (2, inst, (imm & 0x1f), 5);
+ }
+ break;
+ }
+ case LRW_DISP16:
+ {
+ unsigned int inst = csky_read_insn (buf, 2);
+ inst = CSKYV2_INST_LRW32 | (((inst & 0xe0) >> 5) << 16);
+ if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
+ fix_new (fragp, fragp->fr_fix, 4,
+ fragp->fr_symbol, fragp->fr_offset, 1,
+ BFD_RELOC_CKCORE_PCREL_IMM16BY4);
+ make_insn (4, inst, ((disp + 2) >> 2), 16);
+ break;
+ }
+ case JCOMPZ_DISP16:
+ {
+ unsigned int inst = csky_read_insn (buf, 4);
+ make_insn (4, inst, disp >> 1, 16);
+ }
+ break;
+ case JCOMPZ_DISP32:
+ {
+ unsigned int inst = csky_read_insn (buf, 4);
+ int literal_offset;
+ make_insn (4, opposite_of_stored_compz (inst),
+ (4 + 4 + PAD_LITERAL_LENGTH) >> 1, 16);
+ literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
+ ? 0 : 2);
+ make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
+ make_literal (fragp, literal_offset);
+ }
+ break;
+ case JUNCD_DISP16:
+ case UNCD_DISP16:
+ {
+ if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
+ fix_new (fragp, fragp->fr_fix, 4,
+ fragp->fr_symbol, fragp->fr_offset, 1,
+ BFD_RELOC_CKCORE_PCREL_IMM16BY2);
+ make_insn (4, CSKYV2_INST_BR32, disp >> 1, 16);
+ }
+ break;
+ case JCOND_DISP32:
+ {
+ /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
+ unsigned int inst = csky_read_insn (buf, 2);
+ int literal_offset;
+
+ if (inst == CSKYV2_INST_BT16)
+ inst = CSKYV2_INST_BF16;
+ else
+ inst = CSKYV2_INST_BT16;
+ make_insn (2, inst, (2 + 4 + PAD_LITERAL_LENGTH) >> 1, 10);
+ literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
+ ? 0 : 2);
+ make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
+ make_literal (fragp, literal_offset);
+ break;
+ }
+ case JUNCD_DISP32:
+ {
+ int literal_offset;
+ literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
+ ? 0 : 2);
+ make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
+ make_literal (fragp, literal_offset);
+ }
+ break;
+ case RELAX_OVERFLOW:
+ csky_branch_report_error (fragp->fr_file, fragp->fr_line,
+ fragp->fr_symbol, disp);
+ break;
+ default:
+ abort ();
+ break;
+ }
+}
+
+/* Round up a section size to the appropriate boundary. */
+
+valueT
+md_section_align (segT segment ATTRIBUTE_UNUSED,
+ valueT size)
+{
+ return size;
+}
+
+/* MD interface: Symbol and relocation handling. */
+
+void md_csky_end (void)
+{
+ dump_literals (0);
+}
+
+/* Return the address within the segment that a PC-relative fixup is
+ relative to. */
+
+long
+md_pcrel_from_section (fixS * fixP, segT seg)
+{
+ /* If the symbol is undefined or defined in another section
+ we leave the add number alone for the linker to fix it later. */
+ if (fixP->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || S_GET_SEGMENT (fixP->fx_addsy) != seg))
+ return fixP->fx_size;
+
+ /* The case where we are going to resolve things. */
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* csky_cons_fix_new is called via the expression parsing code when a
+ reloc is needed. We use this hook to get the correct .got reloc. */
+
+void
+csky_cons_fix_new (fragS *frag,
+ unsigned int off,
+ unsigned int len,
+ expressionS *exp,
+ bfd_reloc_code_real_type reloc)
+{
+ fixS *fixP;
+
+ if (BFD_RELOC_CKCORE_GOTOFF == insn_reloc
+ || BFD_RELOC_CKCORE_GOTPC == insn_reloc
+ || BFD_RELOC_CKCORE_GOT32 == insn_reloc
+ || BFD_RELOC_CKCORE_PLT32 == insn_reloc
+ || BFD_RELOC_CKCORE_TLS_LE32 == insn_reloc
+ || BFD_RELOC_CKCORE_TLS_GD32 == insn_reloc
+ || BFD_RELOC_CKCORE_TLS_LDM32 == insn_reloc
+ || BFD_RELOC_CKCORE_TLS_LDO32 == insn_reloc
+ || BFD_RELOC_CKCORE_TLS_IE32 == insn_reloc)
+ reloc = insn_reloc;
+ else
+ switch (len)
+ {
+ case 1:
+ reloc = BFD_RELOC_8;
+ break;
+ case 2:
+ reloc = BFD_RELOC_16;
+ break;
+ case 4:
+ reloc = BFD_RELOC_32;
+ break;
+ case 8:
+ reloc = BFD_RELOC_64;
+ break;
+ default:
+ as_bad (_("unsupported BFD relocation size %d"), len);
+ reloc = BFD_RELOC_32;
+ break;
+ }
+ fixP = fix_new_exp (frag, off, (int) len, exp, 0, reloc);
+ if (BFD_RELOC_CKCORE_TLS_IE32 == insn_reloc
+ || BFD_RELOC_CKCORE_TLS_GD32 == insn_reloc
+ || BFD_RELOC_CKCORE_TLS_LDM32 == insn_reloc)
+ {
+ fixP->tc_fix_data.frag = literal_insn_offset->tls_addend.frag;
+ fixP->tc_fix_data.offset = literal_insn_offset->tls_addend.offset;
+ }
+}
+
+/* See whether we need to force a relocation into the output file.
+ This is used to force out switch and PC relative relocations when
+ relaxing. */
+
+int
+csky_force_relocation (fixS * fix)
+{
+ if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fix->fx_r_type == BFD_RELOC_RVA
+ || fix->fx_r_type == BFD_RELOC_CKCORE_ADDR_HI16
+ || fix->fx_r_type == BFD_RELOC_CKCORE_ADDR_LO16
+ || fix->fx_r_type == BFD_RELOC_CKCORE_TOFFSET_LO16
+ || fix->fx_r_type == BFD_RELOC_CKCORE_DOFFSET_LO16)
+ return 1;
+
+ if (fix->fx_addsy == NULL)
+ return 0;
+
+ if (do_use_branchstub
+ && fix->fx_r_type == BFD_RELOC_CKCORE_PCREL_IMM26BY2
+ && (symbol_get_bfdsym (fix->fx_addsy)->flags & BSF_FUNCTION))
+ return 1;
+ return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL);
+}
+
+/* Return true if the fix can be handled by GAS, false if it must
+ be passed through to the linker. */
+
+bfd_boolean
+csky_fix_adjustable (fixS * fixP)
+{
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* We need the symbol name for the VTABLE entries. */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT32
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT32
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT12
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT12
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_HI16
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_LO16
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_HI16
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_LO16
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_HI16
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_LO16
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR_HI16
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR_LO16
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_IMM18BY4
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_IMM18BY4
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_IMM18
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LE32
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_IE32
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_GD32
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LDM32
+ || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LDO32)
+ return 0;
+
+ if (do_use_branchstub
+ && fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_IMM26BY2
+ && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION))
+ return 0;
+
+ return 1;
+}
+
+void
+md_apply_fix (fixS *fixP,
+ valueT *valP,
+ segT seg)
+{
+ reloc_howto_type *howto;
+ /* Note: use offsetT because it is signed, valueT is unsigned. */
+ offsetT val = *valP;
+ char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+
+ /* if fx_done = 0, fixup will also be processed in
+ * tc_gen_reloc() after md_apply_fix(). */
+ fixP->fx_done = 0;
+
+ /* If the fix is relative to a symbol which is not defined, or not
+ in the same segment as the fix, we cannot resolve it here. */
+ if (IS_CSKY_V1 (mach_flag) && fixP->fx_addsy != NULL
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || S_GET_SEGMENT (fixP->fx_addsy) != seg))
+ {
+ switch (fixP->fx_r_type)
+ {
+ /* Data fx_addnumber is greater than 16 bits,
+ so fx_addnumber is assigned zero. */
+ case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
+ *valP = 0;
+ break;
+ case BFD_RELOC_CKCORE_TLS_IE32:
+ case BFD_RELOC_CKCORE_TLS_LDM32:
+ case BFD_RELOC_CKCORE_TLS_GD32:
+ {
+ struct tls_addend *ta = &(fixP->tc_fix_data);
+ fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
+ - (ta->frag->fr_address + ta->offset));
+ }
+ /* Fall through. */
+ case BFD_RELOC_CKCORE_TLS_LE32:
+ case BFD_RELOC_CKCORE_TLS_LDO32:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+ default:
+ break;
+ }
+#ifdef OBJ_ELF
+ /* For ELF we can just return and let the reloc that will be generated
+ take care of everything. For COFF we still have to insert 'val'
+ into the insn since the addend field will be ignored. */
+ return;
+#endif
+ }
+
+ /* We can handle these relocs. */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_CKCORE_PCREL32:
+ break;
+ case BFD_RELOC_VTABLE_INHERIT:
+ fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTINHERIT;
+ if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy)
+ && !S_IS_WEAK (fixP->fx_addsy))
+ S_SET_WEAK (fixP->fx_addsy);
+ break;
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTENTRY;
+ break;
+ case BFD_RELOC_CKCORE_GOT12:
+ case BFD_RELOC_CKCORE_PLT12:
+ case BFD_RELOC_CKCORE_ADDR_HI16:
+ case BFD_RELOC_CKCORE_ADDR_LO16:
+ case BFD_RELOC_CKCORE_TOFFSET_LO16:
+ case BFD_RELOC_CKCORE_DOFFSET_LO16:
+ case BFD_RELOC_CKCORE_GOT_HI16:
+ case BFD_RELOC_CKCORE_GOT_LO16:
+ case BFD_RELOC_CKCORE_PLT_HI16:
+ case BFD_RELOC_CKCORE_PLT_LO16:
+ case BFD_RELOC_CKCORE_GOTPC_HI16:
+ case BFD_RELOC_CKCORE_GOTPC_LO16:
+ case BFD_RELOC_CKCORE_GOTOFF_HI16:
+ case BFD_RELOC_CKCORE_GOTOFF_LO16:
+ case BFD_RELOC_CKCORE_DOFFSET_IMM18:
+ case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2:
+ case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4:
+ case BFD_RELOC_CKCORE_GOTOFF_IMM18:
+ case BFD_RELOC_CKCORE_GOT_IMM18BY4:
+ case BFD_RELOC_CKCORE_PLT_IMM18BY4:
+ break;
+ case BFD_RELOC_CKCORE_TLS_IE32:
+ case BFD_RELOC_CKCORE_TLS_LDM32:
+ case BFD_RELOC_CKCORE_TLS_GD32:
+ {
+ struct tls_addend *ta = &(fixP->tc_fix_data);
+ fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
+ - (ta->frag->fr_address + ta->offset));
+ }
+ /* Fall through. */
+ case BFD_RELOC_CKCORE_TLS_LE32:
+ case BFD_RELOC_CKCORE_TLS_LDO32:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_CKCORE_ADDR32;
+ /* Fall through. */
+ case BFD_RELOC_16:
+ case BFD_RELOC_8:
+ if (fixP->fx_addsy == NULL)
+ {
+ if (fixP->fx_size == 4)
+ ;
+ else if (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
+ ;
+ else if (fixP->fx_size == 1 && val >= -256 && val <= 255)
+ ;
+ else
+ abort ();
+ md_number_to_chars (buf, val, fixP->fx_size);
+ fixP->fx_done = 1;
+ }
+ break;
+ case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
+ if (fixP->fx_addsy == 0 && val > -2 KB && val < 2 KB)
+ {
+ long nval = (val >> 1) & 0x7ff;
+ nval |= CSKYV1_INST_BSR;
+ csky_write_insn (buf, nval, 2);
+ fixP->fx_done = 1;
+ }
+ else
+ *valP = 0;
+ break;
+ case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2:
+ if (fixP->fx_addsy == 0)
+ {
+ if (val >= -(1 << 26) && val < (1 << 26))
+ {
+ unsigned int nval = ((val + fixP->fx_size) >> 1) & 0x3ffffff;
+ nval |= CSKYV2_INST_BSR32;
+
+ csky_write_insn (buf, nval, 4);
+ }
+ /* If bsr32 cannot reach,
+ generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
+ else if (IS_CSKY_ARCH_810 (mach_flag))
+ {
+ howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ valueT opcode = csky_read_insn (buf, 4);
+ opcode = (opcode & howto->dst_mask) | CSKYV2_INST_JSRI_TO_LRW;
+ csky_write_insn (buf, opcode, 4);
+ opcode = CSKYV2_INST_JSR_R26;
+ csky_write_insn (buf + 4, opcode, 4);
+ }
+ fixP->fx_done = 1;
+ }
+ break;
+
+ default:
+ {
+ valueT opcode;
+ offsetT min, max;
+ unsigned int issigned = 0;
+
+ if (fixP->fx_addsy)
+ break;
+
+ howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (howto == NULL)
+ {
+ if (fixP->fx_size == 4
+ || (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
+ || (fixP->fx_size == 1 && val >= -256 && val <= 255))
+ {
+ md_number_to_chars (buf, val, fixP->fx_size);
+ fixP->fx_done = 1;
+ break;
+ }
+ else
+ abort ();
+ }
+
+ if (IS_CSKY_V2 (mach_flag))
+ val += fixP->fx_size;
+
+ if (howto->rightshift == 2)
+ val += 2;
+
+ val >>= howto->rightshift;
+
+ switch (fixP->fx_r_type)
+ {
+ /* Offset is unsigned. */
+ case BFD_RELOC_CKCORE_PCREL_IMM8BY4:
+ case BFD_RELOC_CKCORE_PCREL_IMM10BY4:
+ case BFD_RELOC_CKCORE_PCREL_IMM16BY4:
+ max = (offsetT) howto->dst_mask;
+ min = 0;
+ break;
+ /* lrw16. */
+ case BFD_RELOC_CKCORE_PCREL_IMM7BY4:
+ if (do_extend_lrw)
+ max = (offsetT)((1 << (howto->bitsize + 1)) - 2);
+ else
+ max = (offsetT)((1 << howto->bitsize) - 1);
+ min = 0;
+ break;
+ /* flrws, flrwd: the offset bits are divided in two parts. */
+ case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4:
+ max = (offsetT)((1 << howto->bitsize) - 1);
+ min = 0;
+ break;
+ /* Offset is signed. */
+ default:
+ max = (offsetT)(howto->dst_mask >> 1);
+ min = - max - 1;
+ issigned = 1;
+ }
+ if (val < min || val > max)
+ {
+ csky_branch_report_error (fixP->fx_file, fixP->fx_line,
+ fixP->fx_addsy, val);
+ return;
+ }
+ opcode = csky_read_insn (buf, fixP->fx_size);
+ /* Clear redundant bits brought from the last
+ operation if there is any. */
+ if (do_extend_lrw && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
+ val &= 0xff;
+ else
+ val &= issigned ? (offsetT)(howto->dst_mask) : max;
+
+ if (fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4)
+ val = (val & 0xf) << 12;
+
+ if (fixP->fx_size == 2 && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
+ {
+ /* 8 bit offset lrw16. */
+ if (val >= 0x80)
+ csky_write_insn (buf,
+ ((~val & 0x1f)
+ | ((~val & 0x60) << 3) | (opcode & 0xe0)),
+ fixP->fx_size);
+ /* 7 bit offset lrw16. */
+ else
+ csky_write_insn (buf,
+ (val & 0x1f) | ((val & 0x60) << 3) | opcode,
+ fixP->fx_size);
+ }
+ else if (fixP->fx_size == 4
+ && (opcode & 0xfe1ffe00) == CSKYV2_INST_FLRW)
+ csky_write_insn (buf,
+ ((val & 0xf) << 4) | ((val & 0xf0) << 17) | opcode,
+ fixP->fx_size);
+ else
+ csky_write_insn (buf, val | opcode, fixP->fx_size);
+ fixP->fx_done = 1;
+ break;
+ }
+ }
+ fixP->fx_addnumber = val;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+
+arelent *
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
+{
+ arelent *rel;
+
+ rel = xmalloc (sizeof (arelent));
+ rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
+ rel->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ rel->addend = fixP->fx_offset;
+ if (rel->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));
+
+ /* Set howto to a garbage value so that we can keep going. */
+ rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
+ }
+ gas_assert (rel->howto != NULL);
+ rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
+ return rel;
+}
+
+/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
+
+long
+csky_relax_frag (segT segment, fragS *fragP, long stretch)
+{
+ const relax_typeS *this_type;
+ const relax_typeS *start_type;
+ relax_substateT next_state;
+ relax_substateT this_state;
+ offsetT growth;
+ offsetT aim;
+ addressT target;
+ addressT address;
+ symbolS *symbolP;
+ const relax_typeS *table;
+
+ target = fragP->fr_offset;
+ address = fragP->fr_address;
+ table = TC_GENERIC_RELAX_TABLE;
+ this_state = fragP->fr_subtype;
+ start_type = this_type = table + this_state;
+ symbolP = fragP->fr_symbol;
+
+ if (symbolP)
+ {
+ fragS *sym_frag;
+
+ sym_frag = symbol_get_frag (symbolP);
+
+#ifndef DIFF_EXPR_OK
+ know (sym_frag != NULL);
+#endif
+ know (S_GET_SEGMENT (symbolP) != absolute_section
+ || sym_frag == &zero_address_frag);
+ target += S_GET_VALUE (symbolP);
+
+ /* If SYM_FRAG has yet to be reached on this pass, assume it
+ will move by STRETCH just as we did, unless there is an
+ alignment frag between here and SYM_FRAG. An alignment may
+ well absorb any STRETCH, and we don't want to choose a larger
+ branch insn by overestimating the needed reach of this
+ branch. It isn't critical to calculate TARGET exactly; We
+ know we'll be doing another pass if STRETCH is non-zero. */
+
+ if (stretch != 0
+ && sym_frag->relax_marker != fragP->relax_marker
+ && S_GET_SEGMENT (symbolP) == segment)
+ {
+ fragS *f;
+
+ /* Adjust stretch for any alignment frag. Note that if have
+ been expanding the earlier code, the symbol may be
+ defined in what appears to be an earlier frag. FIXME:
+ This doesn't handle the fr_subtype field, which specifies
+ a maximum number of bytes to skip when doing an
+ alignment. */
+ for (f = fragP; f != NULL && f != sym_frag; f = f->fr_next)
+ {
+ if (f->fr_type == rs_align || f->fr_type == rs_align_code)
+ {
+ if (stretch < 0)
+ stretch = -((-stretch)
+ & ~((1 << (int) f->fr_offset) - 1));
+ else
+ stretch &= ~((1 << (int) f->fr_offset) - 1);
+ }
+ if (stretch == 0)
+ break;
+ }
+ if (f != 0)
+ target += stretch;
+ }
+ }
+
+ aim = target - address - fragP->fr_fix;
+
+ /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
+ if (fragP->fr_symbol && S_GET_SEGMENT (symbolP) != segment)
+ aim = 0;
+
+ if (aim < 0)
+ {
+ /* Look backwards. */
+ for (next_state = this_type->rlx_more; next_state;)
+ if (aim >= this_type->rlx_backward)
+ next_state = 0;
+ else
+ {
+ /* Grow to next state. */
+ this_state = next_state;
+ this_type = table + this_state;
+ next_state = this_type->rlx_more;
+ }
+ }
+ else
+ {
+ /* Look forwards. */
+ for (next_state = this_type->rlx_more; next_state;)
+ if (aim <= this_type->rlx_forward)
+ next_state = 0;
+ else
+ {
+ /* Grow to next state. */
+ this_state = next_state;
+ this_type = table + this_state;
+ next_state = this_type->rlx_more;
+ }
+ }
+
+ growth = this_type->rlx_length - start_type->rlx_length;
+ if (growth != 0)
+ fragP->fr_subtype = this_state;
+ return growth;
+}
+
+int
+md_estimate_size_before_relax (fragS * fragp,
+ segT segtype)
+{
+ switch (fragp->fr_subtype)
+ {
+ case COND_DISP10:
+ case COND_DISP16:
+ case SCOND_DISP10:
+ case SCOND_DISP16:
+ case UNCD_DISP10:
+ case UNCD_DISP16:
+ case JCOND_DISP10:
+ case JCOND_DISP16:
+ case JCOND_DISP32:
+ case JUNCD_DISP10:
+ case JUNCD_DISP16:
+ case JUNCD_DISP32:
+ case JCOMPZ_DISP16:
+ case JCOMPZ_DISP32:
+ case BSR_DISP26:
+ case LRW_DISP7:
+ case LRW2_DISP8:
+ case LRW_DISP16:
+ gas_assert (fragp->fr_symbol);
+ if (IS_EXTERNAL_SYM (fragp->fr_symbol, segtype))
+ while (csky_relax_table[fragp->fr_subtype].rlx_more > RELAX_OVERFLOW)
+ fragp->fr_subtype = csky_relax_table[fragp->fr_subtype].rlx_more;
+ return csky_relax_table[fragp->fr_subtype].rlx_length;
+
+ /* C-SKY V1 relaxes. */
+ case C (UNCD_JUMP, UNDEF_DISP):
+ case C (UNCD_JUMP_PIC, UNDEF_DISP):
+ if (!fragp->fr_symbol)
+ fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
+ else if (S_GET_SEGMENT (fragp->fr_symbol) == segtype)
+ fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
+ else
+ fragp->fr_subtype = C (UNCD_JUMP_S, UNDEF_WORD_DISP);
+ break;
+
+ case C (COND_JUMP, UNDEF_DISP):
+ case C (COND_JUMP_PIC, UNDEF_DISP):
+ if (fragp->fr_symbol
+ && S_GET_SEGMENT (fragp->fr_symbol) == segtype)
+ /* Got a symbol and it's defined in this segment, become byte
+ sized. Maybe it will fix up. */
+ fragp->fr_subtype = C (COND_JUMP_S, DISP12);
+ else if (fragp->fr_symbol)
+ /* It's got a segment, but it's not ours, so it will always be
+ long. */
+ fragp->fr_subtype = C (COND_JUMP_S, UNDEF_WORD_DISP);
+ else
+ /* We know the abs value. */
+ fragp->fr_subtype = C (COND_JUMP_S, DISP12);
+ break;
+
+ case C (UNCD_JUMP, DISP12):
+ case C (UNCD_JUMP, DISP32):
+ case C (UNCD_JUMP, UNDEF_WORD_DISP):
+ case C (COND_JUMP, DISP12):
+ case C (COND_JUMP, DISP32):
+ case C (COND_JUMP, UNDEF_WORD_DISP):
+ case C (UNCD_JUMP_PIC, DISP12):
+ case C (UNCD_JUMP_PIC, DISP32):
+ case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
+ case C (COND_JUMP_PIC, DISP12):
+ case C (COND_JUMP_PIC, DISP32):
+ case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
+ case RELAX_OVERFLOW:
+ break;
+
+ default:
+ abort ();
+ }
+ return csky_relax_table[fragp->fr_subtype].rlx_length;
+}
+
+/* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
+
+static void
+csky_macro_md_assemble (const char *op,
+ const char *oprnd1,
+ const char *oprnd2,
+ const char *oprnd3)
+{
+ char str[80];
+ str[0] = '\0';
+ strcat (str, op);
+ if (oprnd1 != NULL)
+ {
+ strcat (str, " ");
+ strcat (str, oprnd1);
+ if (oprnd2 != NULL)
+ {
+ strcat (str, ",");
+ strcat (str, oprnd2);
+ if (oprnd3 != NULL)
+ {
+ strcat (str, ",");
+ strcat (str, oprnd3);
+ }
+ }
+ }
+ md_assemble (str);
+ return;
+}
+
+/* Get the string of operand. */
+
+static int
+csky_get_macro_operand (char *src_s, char *dst_s, char end_sym)
+{
+ int nlen = 0;
+ while (ISSPACE (*src_s))
+ ++src_s;
+ while (*src_s != end_sym)
+ dst_s[nlen++] = *(src_s++);
+ dst_s[nlen] = '\0';
+ return nlen;
+}
+
+/* idly 4 -> idly4. */
+
+static void
+csky_idly (void)
+{
+ char *s = csky_insn.opcode_end;
+ if (!is_imm_over_range (&s, 4, 4, -1))
+ {
+ as_bad (_("second operand must be 4"));
+ return;
+ }
+ csky_macro_md_assemble ("idly4", NULL, NULL, NULL);
+ return;
+}
+
+/* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
+
+static void
+csky_rolc (void)
+{
+ char reg[10];
+ char *s = csky_insn.opcode_end;
+
+ s += csky_get_macro_operand (s, reg, ',');
+ ++s;
+
+ if (is_imm_over_range (&s, 1, 1, -1))
+ {
+ csky_macro_md_assemble ("addc", reg, reg, NULL);
+ return;
+ }
+ else
+ as_bad (_("second operand must be 1"));
+}
+
+/* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
+
+static void
+csky_sxtrb (void)
+{
+ char reg1[10];
+ char reg2[10];
+
+ char *s = csky_insn.opcode_end;
+ s += csky_get_macro_operand (s, reg1, ',');
+ ++s;
+ csky_get_macro_operand (s, reg2, '\0');
+
+ csky_macro_md_assemble (csky_insn.macro->name + 1, reg1, reg2, NULL);
+ csky_macro_md_assemble ("sextb", reg1, NULL, NULL);
+ return;
+}
+
+static void
+csky_movtf (void)
+{
+ char reg1[10];
+ char reg2[10];
+ char reg3[10];
+
+ char *s = csky_insn.opcode_end;
+ s += csky_get_macro_operand (s, reg1, ',');
+ ++s;
+
+ s += csky_get_macro_operand (s, reg2, ',');
+ ++s;
+
+ s += csky_get_macro_operand (s, reg3, '\0');
+ ++s;
+ csky_macro_md_assemble ("movt", reg1, reg2, NULL);
+ csky_macro_md_assemble ("movf", reg1, reg3, NULL);
+ return;
+}
+
+static bfd_boolean
+get_macro_reg_vals (int *reg1, int *reg2, int *reg3)
+{
+ int nlen;
+ char *s = csky_insn.opcode_end;
+
+ *reg1 = csky_get_reg_val (s, &nlen);
+ s += nlen;
+ if (*s != ',')
+ {
+ csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
+ return FALSE;
+ }
+ s++;
+ *reg2 = csky_get_reg_val (s, &nlen);
+ s += nlen;
+ if (*s != ',')
+ {
+ csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
+ return FALSE;
+ }
+ s++;
+ *reg3 = csky_get_reg_val (s, &nlen);
+ s += nlen;
+ if (*s != '\0')
+ {
+ csky_show_error (ERROR_BAD_END, 0, NULL, NULL);
+ return FALSE;
+ }
+ if (*reg1 == -1 || *reg2 == -1 || *reg3 == -1)
+ {
+ as_bad (_("register number out of range"));
+ return FALSE;
+ }
+ if (*reg1 != *reg2)
+ {
+ as_bad (_("dest and source1 must be the same register"));
+ return FALSE;
+ }
+ if (*reg1 >= 15 || *reg3 >= 15)
+ {
+ as_bad (_("64-bit operator src/dst register must be less than 15"));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
+
+static void
+csky_addc64 (void)
+{
+ int reg1;
+ int reg2;
+ int reg3;
+
+ if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
+ return;
+ csky_macro_md_assemble ("cmplt",
+ csky_general_reg[reg1],
+ csky_general_reg[reg1],
+ NULL);
+ csky_macro_md_assemble ("addc",
+ csky_general_reg[reg1 + (target_big_endian ? 1 : 0)],
+ csky_general_reg[reg3 + (target_big_endian ? 1 : 0)],
+ NULL);
+ csky_macro_md_assemble ("addc",
+ csky_general_reg[reg1 + (target_big_endian ? 0 : 1)],
+ csky_general_reg[reg3 + (target_big_endian ? 0 : 1)],
+ NULL);
+ return;
+}
+
+/* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
+
+static void
+csky_subc64 (void)
+{
+ int reg1;
+ int reg2;
+ int reg3;
+
+ if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
+ return;
+ csky_macro_md_assemble ("cmphs",
+ csky_general_reg[reg1],
+ csky_general_reg[reg1],
+ NULL);
+ csky_macro_md_assemble ("subc",
+ csky_general_reg[reg1 + (target_big_endian ? 1 : 0)],
+ csky_general_reg[reg3 + (target_big_endian ? 1 : 0)],
+ NULL);
+ csky_macro_md_assemble ("subc",
+ csky_general_reg[reg1 + (target_big_endian ? 0 : 1)],
+ csky_general_reg[reg3 + (target_big_endian ? 0 : 1)],
+ NULL);
+ return;
+}
+
+/* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
+
+static void
+csky_or64 (void)
+{
+ int reg1;
+ int reg2;
+ int reg3;
+
+ if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
+ return;
+ csky_macro_md_assemble ("or",
+ csky_general_reg[reg1 + (target_big_endian ? 1 : 0)],
+ csky_general_reg[reg3 + (target_big_endian ? 1 : 0)],
+ NULL);
+ csky_macro_md_assemble ("or",
+ csky_general_reg[reg1 + (target_big_endian ? 0 : 1)],
+ csky_general_reg[reg3 + (target_big_endian ? 0 : 1)],
+ NULL);
+ return;
+}
+
+/* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
+
+static void
+csky_xor64 (void)
+{
+ int reg1;
+ int reg2;
+ int reg3;
+
+ if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
+ return;
+ csky_macro_md_assemble ("xor",
+ csky_general_reg[reg1 + (target_big_endian ? 1 : 0)],
+ csky_general_reg[reg3 + (target_big_endian ? 1 : 0)],
+ NULL);
+ csky_macro_md_assemble ("xor",
+ csky_general_reg[reg1 + (target_big_endian ? 0 : 1)],
+ csky_general_reg[reg3 + (target_big_endian ? 0 : 1)],
+ NULL);
+ return;
+}
+
+/* The following are V2 macro instructions. */
+
+/* neg rd -> not rd, rd; addi rd, 1. */
+
+static void
+csky_neg (void)
+{
+ char reg1[10];
+
+ char *s = csky_insn.opcode_end;
+ s += csky_get_macro_operand (s, reg1, '\0');
+ ++s;
+
+ csky_macro_md_assemble ("not", reg1, reg1, NULL);
+ csky_macro_md_assemble ("addi", reg1, "1", NULL);
+ return;
+}
+
+/* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
+
+static void
+csky_rsubi (void)
+{
+ char reg1[10];
+ char str_imm16[20];
+ unsigned int imm16 = 0;
+ expressionS e;
+ char *s = csky_insn.opcode_end;
+ s += csky_get_macro_operand (s, reg1, ',');
+ ++s;
+
+ s = parse_exp (s, &e);
+ if (e.X_op == O_constant)
+ imm16 = e.X_add_number;
+ else
+ csky_show_error (ERROR_IMM_ILLEGAL, 2, NULL, NULL);
+
+ sprintf (str_imm16, "%d", imm16 + 1);
+
+ csky_macro_md_assemble ("not", reg1, reg1, NULL);
+ csky_macro_md_assemble ("addi", reg1, str_imm16, NULL);
+ return;
+}
+
+/* Such as: asrc rd -> asrc rd, rd, 1. */
+
+static void
+csky_arith (void)
+{
+ char reg1[10];
+ char *s = csky_insn.opcode_end;
+ s += csky_get_macro_operand (s, reg1, '\0');
+ ++s;
+ csky_macro_md_assemble (csky_insn.macro->name, reg1, reg1, "1");
+ return;
+}
+
+/* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
+ else: decne rd, rd, 1 */
+
+static void
+csky_decne (void)
+{
+ char reg1[10];
+ char *s = csky_insn.opcode_end;
+ s += csky_get_macro_operand (s, reg1, '\0');
+ ++s;
+ if (IS_CSKY_ARCH_802 (mach_flag))
+ {
+ csky_macro_md_assemble ("subi", reg1, "1", NULL);
+ csky_macro_md_assemble ("cmpnei", reg1, "0", NULL);
+ }
+ else
+ csky_macro_md_assemble ("decne", reg1, reg1, "1");
+ return;
+}
+
+/* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
+
+static void
+csky_lrw (void)
+{
+ char reg1[10];
+ char imm[40];
+ char imm_hi16[40];
+ char imm_lo16[40];
+
+ char *s = csky_insn.opcode_end;
+ s += csky_get_macro_operand (s, reg1, ',');
+ ++s;
+ s += csky_get_macro_operand (s, imm, '\0');
+ ++s;
+
+ imm_hi16[0] = '\0';
+ strcat (imm_hi16, "(");
+ strcat (imm_hi16, imm);
+ strcat (imm_hi16, ") >> 16");
+ imm_lo16[0] = '\0';
+ strcat (imm_lo16, "(");
+ strcat (imm_lo16, imm);
+ strcat (imm_lo16, ") & 0xffff");
+
+ csky_macro_md_assemble ("movih", reg1, imm_hi16, NULL);
+ csky_macro_md_assemble ("ori", reg1, reg1, imm_lo16);
+
+ return;
+}
+
+/* The following are worker functions for C-SKY v1. */
+
+bfd_boolean
+v1_work_lrw (void)
+{
+ int reg;
+ int output_literal = csky_insn.val[1];
+
+ reg = csky_insn.val[0];
+ csky_insn.isize = 2;
+ csky_insn.output = frag_more (2);
+ if (csky_insn.e1.X_op == O_constant
+ && csky_insn.e1.X_add_number <= 0x7f
+ && csky_insn.e1.X_add_number >= 0)
+ /* lrw to movi. */
+ csky_insn.inst = 0x6000 | reg | (csky_insn.e1.X_add_number << 4);
+ else
+ {
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode;
+ csky_insn.inst |= reg << 8;
+ if (output_literal)
+ {
+ int n = enter_literal (&csky_insn.e1, 0, 0, 0);
+
+ /* Create a reference to pool entry. */
+ csky_insn.e1.X_op = O_symbol;
+ csky_insn.e1.X_add_symbol = poolsym;
+ csky_insn.e1.X_add_number = n << 2;
+ }
+
+ if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
+ {
+ literal_insn_offset->tls_addend.frag = frag_now;
+ literal_insn_offset->tls_addend.offset
+ = (csky_insn.output
+ - literal_insn_offset->tls_addend.frag->fr_literal);
+ }
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal, 2,
+ &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
+ }
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+
+ return TRUE;
+}
+
+bfd_boolean
+v1_work_fpu_fo (void)
+{
+ int i = 0;
+ int inst;
+ int greg = -1;
+ char buff[50];
+ struct csky_opcode_info *opinfo = NULL;
+
+ if (csky_insn.isize == 4)
+ opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
+ else if (csky_insn.isize == 2)
+ opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
+
+ /* Firstly, get general reg. */
+ for (i = 0;i < opinfo->operand_num; i++)
+ if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
+ greg = csky_insn.val[i];
+ gas_assert (greg != -1);
+
+ /* Secondly, get float inst. */
+ csky_generate_insn ();
+ inst = csky_insn.inst;
+
+ /* Now get greg and inst, we can write instruction to floating unit. */
+ sprintf (buff, "lrw %s,0x%x", csky_general_reg[greg], inst);
+ md_assemble (buff);
+ sprintf (buff, "cpwir %s", csky_general_reg[greg]);
+ md_assemble (buff);
+
+ return FALSE;
+}
+
+bfd_boolean
+v1_work_fpu_fo_fc (void)
+{
+ int i = 0;
+ int inst;
+ int greg = -1;
+ char buff[50];
+ struct csky_opcode_info *opinfo = NULL;
+
+ if (csky_insn.isize == 4)
+ opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
+ else if (csky_insn.isize == 2)
+ opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
+
+ /* Firstly, get general reg. */
+ for (i = 0;i < opinfo->operand_num; i++)
+ if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
+ greg = csky_insn.val[i];
+ gas_assert (greg != -1);
+
+ /* Secondly, get float inst. */
+ csky_generate_insn ();
+ inst = csky_insn.inst;
+
+ /* Now get greg and inst, we can write instruction to floating unit. */
+ sprintf (buff, "lrw %s,0x%x", csky_general_reg[greg], inst);
+ md_assemble (buff);
+ sprintf (buff, "cpwir %s", csky_general_reg[greg]);
+ md_assemble (buff);
+ sprintf (buff, "cprc");
+ md_assemble (buff);
+
+ return FALSE;
+}
+
+bfd_boolean
+v1_work_fpu_write (void)
+{
+ int greg;
+ int freg;
+ char buff[50];
+
+ greg = csky_insn.val[0];
+ freg = csky_insn.val[1];
+
+ /* Now get greg and freg, we can write instruction to floating unit. */
+ sprintf (buff, "cpwgr %s,%s", csky_general_reg[greg], csky_cp_reg[freg]);
+ md_assemble (buff);
+
+ return FALSE;
+}
+
+bfd_boolean
+v1_work_fpu_read (void)
+{
+ int greg;
+ int freg;
+ char buff[50];
+
+ greg = csky_insn.val[0];
+ freg = csky_insn.val[1];
+ /* Now get greg and freg, we can write instruction to floating unit. */
+ sprintf (buff, "cprgr %s,%s", csky_general_reg[greg], csky_cp_reg[freg]);
+ md_assemble (buff);
+
+ return FALSE;
+}
+
+bfd_boolean
+v1_work_fpu_writed (void)
+{
+ int greg;
+ int freg;
+ char buff[50];
+
+ greg = csky_insn.val[0];
+ freg = csky_insn.val[1];
+
+ if (greg & 0x1)
+ {
+ as_bad (_("even register number required"));
+ return FALSE;
+ }
+ /* Now get greg and freg, we can write instruction to floating unit. */
+ if (target_big_endian)
+ sprintf (buff, "cpwgr %s,%s",
+ csky_general_reg[greg + 1], csky_cp_reg[freg]);
+ else
+ sprintf (buff, "cpwgr %s,%s",
+ csky_general_reg[greg], csky_cp_reg[freg]);
+ md_assemble (buff);
+ if (target_big_endian)
+ sprintf (buff, "cpwgr %s,%s",
+ csky_general_reg[greg], csky_cp_reg[freg + 1]);
+ else
+ sprintf (buff, "cpwgr %s,%s",
+ csky_general_reg[greg + 1], csky_cp_reg[freg + 1]);
+ md_assemble (buff);
+
+ return FALSE;
+}
+
+bfd_boolean
+v1_work_fpu_readd (void)
+{
+ int greg;
+ int freg;
+ char buff[50];
+
+ greg = csky_insn.val[0];
+ freg = csky_insn.val[1];
+
+ if (greg & 0x1)
+ {
+ as_bad (_("even register number required"));
+ return FALSE;
+ }
+ /* Now get greg and freg, we can write instruction to floating unit. */
+ if (target_big_endian)
+ sprintf (buff, "cprgr %s,%s",
+ csky_general_reg[greg + 1], csky_cp_reg[freg]);
+ else
+ sprintf (buff, "cprgr %s,%s",
+ csky_general_reg[greg], csky_cp_reg[freg]);
+ md_assemble (buff);
+ if (target_big_endian)
+ sprintf (buff, "cprgr %s,%s",
+ csky_general_reg[greg], csky_cp_reg[freg + 1]);
+ else
+ sprintf (buff, "cprgr %s,%s",
+ csky_general_reg[greg + 1], csky_cp_reg[freg + 1]);
+ md_assemble (buff);
+
+ return FALSE;
+}
+
+/* The following are for csky pseudo handling. */
+
+bfd_boolean
+v1_work_jbsr (void)
+{
+ csky_insn.output = frag_more (2);
+ if (do_force2bsr)
+ /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2);
+ else
+ {
+ /* Using jsri instruction. */
+ const char *name = "jsri";
+ csky_insn.opcode = (struct csky_opcode *)
+ hash_find (csky_opcodes_hash, name);
+ csky_insn.opcode_idx = 0;
+ csky_insn.isize = 2;
+
+ int n = enter_literal (&csky_insn.e1, 1, 0, 0);
+
+ /* Create a reference to pool entry. */
+ csky_insn.e1.X_op = O_symbol;
+ csky_insn.e1.X_add_symbol = poolsym;
+ csky_insn.e1.X_add_number = n << 2;
+
+ /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
+
+ if (csky_insn.e1.X_op != O_absent && do_jsri2bsr)
+ /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 2, & (litpool + (csky_insn.e1.X_add_number >> 2))->e,
+ 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2);
+ }
+ csky_generate_insn ();
+
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+
+ return TRUE;
+}
+
+/* The following are worker functions for csky v2 instruction handling. */
+
+/* For nie/nir/ipush/ipop. */
+
+bfd_boolean
+v2_work_istack (void)
+{
+ if (!do_intr_stack)
+ {
+ csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
+ return FALSE;
+ }
+ csky_insn.output = frag_more (csky_insn.isize);
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode;
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_btsti (void)
+{
+ if (!do_extend_lrw
+ && (csky_insn.flag_force == INSN_OPCODE16F
+ || IS_CSKY_ARCH_801 (mach_flag)))
+ {
+ csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
+ return FALSE;
+ }
+ if (!do_extend_lrw && csky_insn.isize == 2)
+ csky_insn.isize = 4;
+ /* Generate relax or reloc if necessary. */
+ csky_generate_frags ();
+ /* Generate the insn by mask. */
+ csky_generate_insn ();
+ /* Write inst to frag. */
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_addi (void)
+{
+ csky_insn.isize = 2;
+ if (csky_insn.number == 2)
+ {
+ if (csky_insn.val[0] == 14
+ && csky_insn.val[1] >= 0 && csky_insn.val[1] <= 0x1fc
+ && (csky_insn.val[1] & 0x3) == 0
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ /* addi sp, sp, imm. */
+ csky_insn.inst = 0x1400 | ((csky_insn.val[1] >> 2) & 0x1f);
+ csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
+ csky_insn.output = frag_more (2);
+ }
+ else if (csky_insn.val[0] < 8
+ && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
+ csky_insn.inst |= (csky_insn.val[1] - 1);
+ csky_insn.output = frag_more (2);
+ }
+ else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
+ && csky_insn.flag_force != INSN_OPCODE16F
+ && !IS_CSKY_ARCH_801 (mach_flag))
+ {
+ csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
+ csky_insn.inst |= csky_insn.val[0] << 16;
+ csky_insn.inst |= (csky_insn.val[1] - 1);
+ csky_insn.isize = 4;
+ csky_insn.output = frag_more (4);
+ }
+ else
+ {
+ csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
+ csky_insn.opcode_end, NULL);
+ return FALSE;
+ }
+ }
+ else if (csky_insn.number == 3)
+ {
+ if (csky_insn.val[0] == 14
+ && csky_insn.val[1] == 14
+ && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
+ && (csky_insn.val[2] & 0x3) == 0
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x1400 | ((csky_insn.val[2] >> 2) & 0x1f);
+ csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
+ csky_insn.output = frag_more (2);
+ }
+ else if (csky_insn.val[0] < 8
+ && csky_insn.val[1] == 14
+ && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x3fc
+ && (csky_insn.val[2] & 0x3) == 0
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x1800 | (csky_insn.val[0] << 8);
+ csky_insn.inst |= csky_insn.val[2] >> 2;
+ csky_insn.output = frag_more (2);
+ }
+ else if (csky_insn.val[0] < 8
+ && csky_insn.val[0] == csky_insn.val[1]
+ && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
+ csky_insn.inst |= (csky_insn.val[2] - 1);
+ csky_insn.output = frag_more (2);
+ }
+ else if (csky_insn.val[0] < 8
+ && csky_insn.val[1] < 8
+ && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x5802 | (csky_insn.val[0] << 5);
+ csky_insn.inst |= csky_insn.val[1] << 8;
+ csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
+ csky_insn.output = frag_more (2);
+ }
+ else if (csky_insn.val[1] == 28
+ && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x40000
+ && csky_insn.flag_force != INSN_OPCODE16F
+ && !IS_CSKY_ARCH_801 (mach_flag))
+ {
+ csky_insn.inst = 0xcc1c0000 | (csky_insn.val[0] << 21);
+ csky_insn.isize = 4;
+ csky_insn.output = frag_more (4);
+ if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
+ {
+ fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
+ 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18);
+ }
+ else
+ csky_insn.inst |= (csky_insn.val[2] - 1);
+ }
+ else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
+ && csky_insn.flag_force != INSN_OPCODE16F
+ && !IS_CSKY_ARCH_801 (mach_flag))
+ {
+ csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
+ csky_insn.inst |= csky_insn.val[1] << 16;
+ csky_insn.inst |= (csky_insn.val[2] - 1);
+ csky_insn.isize = 4;
+ csky_insn.output = frag_more (4);
+ }
+ else
+ {
+ csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
+ (char *)csky_insn.opcode_end, NULL);
+ return FALSE;
+ }
+ }
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_subi (void)
+{
+ csky_insn.isize = 2;
+ if (csky_insn.number == 2)
+ {
+ if (csky_insn.val[0] == 14
+ && csky_insn.val[1] >= 0 && csky_insn.val[2] <= 0x1fc
+ && (csky_insn.val[1] & 0x3) == 0
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x1420 | ((csky_insn.val[1] >> 2) & 0x1f);
+ csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
+ }
+ else if (csky_insn.val[0] < 8
+ && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
+ csky_insn.inst |= (csky_insn.val[1] - 1);
+ }
+ else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
+ && csky_insn.flag_force != INSN_OPCODE16F
+ && !IS_CSKY_ARCH_801 (mach_flag))
+ {
+ csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
+ csky_insn.inst |= csky_insn.val[0] << 16;
+ csky_insn.inst |= (csky_insn.val[1] - 1);
+ csky_insn.isize = 4;
+ }
+ else
+ {
+ csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
+ (char *)csky_insn.opcode_end, NULL);
+ return FALSE;
+ }
+ }
+ else if (csky_insn.number == 3)
+ {
+ if (csky_insn.val[0] == 14
+ && csky_insn.val[1] == 14
+ && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
+ && (csky_insn.val[2] & 0x3) == 0
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x1420 | ((csky_insn.val[2] >> 2) & 0x1f);
+ csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
+ }
+
+ else if (csky_insn.val[0] < 8
+ && csky_insn.val[0] == csky_insn.val[1]
+ && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
+ csky_insn.inst |= (csky_insn.val[2] - 1);
+ }
+ else if (csky_insn.val[0] < 8
+ && csky_insn.val[1] < 8
+ && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
+ && csky_insn.flag_force != INSN_OPCODE32F)
+ {
+ csky_insn.inst = 0x5803 | (csky_insn.val[0] << 5);
+ csky_insn.inst |= csky_insn.val[1] << 8;
+ csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
+ }
+ else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
+ && csky_insn.flag_force != INSN_OPCODE16F
+ && !IS_CSKY_ARCH_801 (mach_flag))
+ {
+ csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
+ csky_insn.inst |= csky_insn.val[1] << 16;
+ csky_insn.inst |= (csky_insn.val[2] - 1);
+ csky_insn.isize = 4;
+ }
+ else
+ {
+ csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
+ (char *)csky_insn.opcode_end, NULL);
+ return FALSE;
+ }
+ }
+ csky_insn.output = frag_more (csky_insn.isize);
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_add_sub (void)
+{
+ if (csky_insn.number == 3
+ && (csky_insn.val[0] == csky_insn.val[1]
+ || csky_insn.val[0] == csky_insn.val[2])
+ && csky_insn.val[0] <= 15
+ && csky_insn.val[1] <= 15
+ && csky_insn.val[2] <= 15)
+ {
+ if (!strstr (csky_insn.opcode->mnemonic, "sub")
+ || csky_insn.val[0] == csky_insn.val[1])
+ {
+ csky_insn.opcode_idx = 0;
+ csky_insn.isize = 2;
+ if (csky_insn.val[0] == csky_insn.val[1])
+ csky_insn.val[1] = csky_insn.val[2];
+
+ csky_insn.number = 2;
+
+ }
+ }
+ if (csky_insn.isize == 4
+ && IS_CSKY_ARCH_801 (mach_flag))
+ {
+ if (csky_insn.number == 3)
+ {
+ if (csky_insn.val[0] > 7)
+ csky_show_error (ERROR_REG_OVER_RANGE, 1,
+ (void *)(long)csky_insn.val[0], NULL);
+ if (csky_insn.val[1] > 7)
+ csky_show_error (ERROR_REG_OVER_RANGE, 2,
+ (void *)(long)csky_insn.val[1], NULL);
+ if (csky_insn.val[2] > 7)
+ csky_show_error (ERROR_REG_OVER_RANGE, 3,
+ (void *)(long)csky_insn.val[2], NULL);
+ }
+ else
+ {
+ if (csky_insn.val[0] > 15)
+ csky_show_error (ERROR_REG_OVER_RANGE, 1,
+ (void *)(long)csky_insn.val[0], NULL);
+ if (csky_insn.val[1] > 15)
+ csky_show_error (ERROR_REG_OVER_RANGE, 2,
+ (void *)(long)csky_insn.val[1], NULL);
+ }
+ return FALSE;
+ }
+ /* sub rz, rx. */
+ /* Generate relax or reloc if necessary. */
+ csky_generate_frags ();
+ /* Generate the insn by mask. */
+ csky_generate_insn ();
+ /* Write inst to frag. */
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_rotlc (void)
+{
+ const char *name = "addc";
+ csky_insn.opcode
+ = (struct csky_opcode *) hash_find (csky_opcodes_hash, name);
+ csky_insn.opcode_idx = 0;
+ if (csky_insn.isize == 2)
+ {
+ /* addc rz, rx. */
+ csky_insn.number = 2;
+ csky_insn.val[1] = csky_insn.val[0];
+ }
+ else
+ {
+ csky_insn.number = 3;
+ /* addc rz, rx, ry. */
+ csky_insn.val[1] = csky_insn.val[0];
+ csky_insn.val[2] = csky_insn.val[0];
+ }
+ /* Generate relax or reloc if necessary. */
+ csky_generate_frags ();
+ /* Generate the insn by mask. */
+ csky_generate_insn ();
+ /* Write inst to frag. */
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_bgeni (void)
+{
+ const char *name = NULL;
+ int imm = csky_insn.val[1];
+ int val = 1 << imm;
+ if (imm < 16)
+ name = "movi";
+ else
+ {
+ name = "movih";
+ val >>= 16;
+ }
+ csky_insn.opcode
+ = (struct csky_opcode *) hash_find (csky_opcodes_hash, name);
+ csky_insn.opcode_idx = 0;
+ csky_insn.val[1] = val;
+
+ /* Generate relax or reloc if necessary. */
+ csky_generate_frags ();
+ /* Generate the insn by mask. */
+ csky_generate_insn ();
+ /* Write inst to frag. */
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_not (void)
+{
+ const char *name = "nor";
+ csky_insn.opcode
+ = (struct csky_opcode *) hash_find (csky_opcodes_hash, name);
+ csky_insn.opcode_idx = 0;
+ if (csky_insn.number == 1)
+ {
+ csky_insn.val[1] = csky_insn.val[0];
+ if (csky_insn.val[0] < 16)
+ {
+ /* 16 bits nor rz, rz. */
+ csky_insn.number = 2;
+ csky_insn.isize = 2;
+ }
+ else
+ {
+ csky_insn.val[2] = csky_insn.val[0];
+ csky_insn.number = 3;
+ csky_insn.isize = 4;
+ }
+ }
+ if (csky_insn.number == 2)
+ {
+ if (csky_insn.val[0] == csky_insn.val[1]
+ && csky_insn.val[0] < 16)
+ {
+ /* 16 bits nor rz, rz. */
+ csky_insn.number = 2;
+ csky_insn.isize = 2;
+ }
+ else
+ {
+ csky_insn.val[2] = csky_insn.val[1];
+ csky_insn.number = 3;
+ csky_insn.isize = 4;
+ }
+ }
+
+ /* Generate relax or reloc if necessary. */
+ csky_generate_frags ();
+ /* Generate the insn by mask. */
+ csky_generate_insn ();
+ /* Write inst to frag. */
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_jbtf (void)
+{
+ if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
+ {
+ csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
+ return FALSE;
+ }
+
+ if (IS_CSKY_ARCH_801 (mach_flag))
+ {
+ /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
+ range larger than SCOND_DISP16. Relax to a short jump around
+ an unconditional branch, and give up if that overflows too. */
+ csky_insn.output = frag_var (rs_machine_dependent,
+ SCOND_DISP16_LEN,
+ SCOND_DISP10_LEN,
+ SCOND_DISP10,
+ csky_insn.e1.X_add_symbol,
+ csky_insn.e1.X_add_number,
+ 0);
+ csky_insn.isize = 2;
+ csky_insn.max = SCOND_DISP16_LEN;
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode;
+ }
+ else if (do_long_jump && !IS_CSKY_ARCH_802 (mach_flag))
+ {
+ /* Generate relax with jcondition.
+ Note that CK802 doesn't support the JMPI instruction so
+ we cannot relax to a jump with a 32-bit offset. */
+ csky_insn.output = frag_var (rs_machine_dependent,
+ JCOND_DISP32_LEN,
+ JCOND_DISP10_LEN,
+ JCOND_DISP10,
+ csky_insn.e1.X_add_symbol,
+ csky_insn.e1.X_add_number,
+ 0);
+ csky_insn.isize = 2;
+ csky_insn.max = JCOND_DISP32_LEN;
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode;
+ }
+ else
+ {
+ /* Generate relax with condition. */
+ csky_insn.output = frag_var (rs_machine_dependent,
+ COND_DISP16_LEN,
+ COND_DISP10_LEN,
+ COND_DISP10,
+ csky_insn.e1.X_add_symbol,
+ csky_insn.e1.X_add_number,
+ 0);
+ csky_insn.isize = 2;
+ csky_insn.max = COND_DISP16_LEN;
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode;
+ }
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_jbr (void)
+{
+ if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
+ {
+ csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
+ return FALSE;
+ }
+
+ if (do_long_jump
+ && !IS_CSKY_ARCH_801 (mach_flag)
+ && !IS_CSKY_ARCH_802 (mach_flag))
+ {
+ csky_insn.output = frag_var (rs_machine_dependent,
+ JUNCD_DISP32_LEN,
+ JUNCD_DISP10_LEN,
+ JUNCD_DISP10,
+ csky_insn.e1.X_add_symbol,
+ csky_insn.e1.X_add_number,
+ 0);
+
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode;
+ csky_insn.max = JUNCD_DISP32_LEN;
+ csky_insn.isize = 2;
+ }
+ else
+ {
+ /* Generate relax with condition. */
+ csky_insn.output = frag_var (rs_machine_dependent,
+ UNCD_DISP16_LEN,
+ UNCD_DISP10_LEN,
+ UNCD_DISP10,
+ csky_insn.e1.X_add_symbol,
+ csky_insn.e1.X_add_number,
+ 0);
+ csky_insn.isize = 2;
+ csky_insn.max = UNCD_DISP16_LEN;
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode;
+
+ }
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+#define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
+#define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
+#define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
+
+bfd_boolean
+v2_work_lrw (void)
+{
+ int reg = csky_insn.val[0];
+ int output_literal = csky_insn.val[1];
+ int is_done = 0;
+
+ /* If the second operand is O_constant, We can use movi/movih
+ instead of lrw. */
+ if (csky_insn.e1.X_op == O_constant)
+ {
+ /* 801 only has movi16. */
+ if (SIZE_V2_MOVI16 (csky_insn.e1.X_add_number) && reg < 8)
+ {
+ /* movi16 instead. */
+ csky_insn.output = frag_more (2);
+ csky_insn.inst = (CSKYV2_INST_MOVI16 | (reg << 8)
+ | (csky_insn.e1.X_add_number));
+ csky_insn.isize = 2;
+ is_done = 1;
+ }
+ else if (SIZE_V2_MOVI32 (csky_insn.e1.X_add_number)
+ && !IS_CSKY_ARCH_801 (mach_flag))
+ {
+ /* movi32 instead. */
+ csky_insn.output = frag_more (4);
+ csky_insn.inst = (CSKYV2_INST_MOVI32 | (reg << 16)
+ | (csky_insn.e1.X_add_number));
+ csky_insn.isize = 4;
+ is_done = 1;
+ }
+ else if (SIZE_V2_MOVIH (csky_insn.e1.X_add_number)
+ && !IS_CSKY_ARCH_801 (mach_flag))
+ {
+ /* movih instead. */
+ csky_insn.output = frag_more (4);
+ csky_insn.inst = (CSKYV2_INST_MOVIH | (reg << 16)
+ | ((csky_insn.e1.X_add_number >> 16) & 0xffff));
+ csky_insn.isize = 4;
+ is_done = 1;
+ }
+ }
+
+ if (is_done)
+ {
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+ }
+
+ if (output_literal)
+ {
+ int n = enter_literal (&csky_insn.e1, 0, 0, 0);
+ /* Create a reference to pool entry. */
+ csky_insn.e1.X_op = O_symbol;
+ csky_insn.e1.X_add_symbol = poolsym;
+ csky_insn.e1.X_add_number = n << 2;
+ }
+ /* If 16bit force. */
+ if (csky_insn.flag_force == INSN_OPCODE16F)
+ {
+ /* Generate fixup. */
+ if (reg > 7)
+ {
+ csky_show_error (ERROR_UNDEFINE, 0,
+ (void *)"The register is out of range.", NULL);
+ return FALSE;
+ }
+ csky_insn.isize = 2;
+ csky_insn.output = frag_more (2);
+
+ if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
+ {
+ literal_insn_offset->tls_addend.frag = frag_now;
+ literal_insn_offset->tls_addend.offset
+ = csky_insn.output - frag_now->fr_literal;
+ }
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
+ csky_insn.max = 4;
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 2, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4);
+ }
+ else if (csky_insn.flag_force == INSN_OPCODE32F)
+ {
+ csky_insn.isize = 4;
+ csky_insn.output = frag_more (4);
+ if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
+ {
+ literal_insn_offset->tls_addend.frag = frag_now;
+ literal_insn_offset->tls_addend.offset
+ = csky_insn.output - frag_now->fr_literal;
+ }
+ csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
+ }
+ else if (!is_done)
+ {
+ if (reg < 8)
+ {
+ csky_insn.isize = 2;
+
+ if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
+ literal_insn_offset->tls_addend.frag = frag_now;
+
+ csky_insn.output = frag_var (rs_machine_dependent,
+ LRW_DISP16_LEN,
+ LRW_DISP7_LEN,
+ (do_extend_lrw
+ ? LRW2_DISP8 : LRW_DISP7),
+ csky_insn.e1.X_add_symbol,
+ csky_insn.e1.X_add_number, 0);
+ if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
+ {
+ if (literal_insn_offset->tls_addend.frag->fr_next != frag_now)
+ literal_insn_offset->tls_addend.frag
+ = literal_insn_offset->tls_addend.frag->fr_next;
+ literal_insn_offset->tls_addend.offset
+ = (csky_insn.output
+ - literal_insn_offset->tls_addend.frag->fr_literal);
+ }
+ csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
+ csky_insn.max = LRW_DISP16_LEN;
+ csky_insn.isize = 2;
+ }
+ else
+ {
+ csky_insn.isize = 4;
+ csky_insn.output = frag_more (4);
+ if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
+ || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
+ {
+ literal_insn_offset->tls_addend.frag = frag_now;
+ literal_insn_offset->tls_addend.offset
+ = csky_insn.output - frag_now->fr_literal;
+ }
+ csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
+ }
+ }
+
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_lrsrsw (void)
+{
+ int reg = csky_insn.val[0];
+ csky_insn.output = frag_more (4);
+ csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 21);
+ csky_insn.isize = 4;
+
+ switch (insn_reloc)
+ {
+ case BFD_RELOC_CKCORE_GOT32:
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4);
+ break;
+ case BFD_RELOC_CKCORE_PLT32:
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4);
+ break;
+ default:
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4);
+ break;
+ }
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_jbsr (void)
+{
+ if (do_force2bsr
+ || IS_CSKY_ARCH_801 (mach_flag)
+ || IS_CSKY_ARCH_802 (mach_flag))
+ {
+ csky_insn.output = frag_more (4);
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2);
+ csky_insn.isize = 4;
+ csky_insn.inst = CSKYV2_INST_BSR32;
+ }
+ else
+ {
+ int n = enter_literal (&csky_insn.e1, 0, 0, 0);
+ csky_insn.output = frag_more (4);
+ csky_insn.e1.X_op = O_symbol;
+ csky_insn.e1.X_add_symbol = poolsym;
+ csky_insn.e1.X_add_number = n << 2;
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
+ if (do_jsri2bsr || IS_CSKY_ARCH_810 (mach_flag))
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4,
+ &(litpool + (csky_insn.e1.X_add_number >> 2))->e,
+ 1,
+ BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
+ csky_insn.inst = CSKYV2_INST_JSRI32;
+ csky_insn.isize = 4;
+ if (IS_CSKY_ARCH_810 (mach_flag))
+ {
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ csky_insn.output = frag_more (4);
+ dwarf2_emit_insn (0);
+ /* Insert "mov r0, r0". */
+ csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
+ csky_insn.max = 8;
+ }
+ }
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_jsri (void)
+{
+ /* dump literal. */
+ int n = enter_literal (&csky_insn.e1, 1, 0, 0);
+ csky_insn.e1.X_op = O_symbol;
+ csky_insn.e1.X_add_symbol = poolsym;
+ csky_insn.e1.X_add_number = n << 2;
+
+ /* Generate relax or reloc if necessary. */
+ csky_generate_frags ();
+ /* Generate the insn by mask. */
+ csky_generate_insn ();
+ /* Write inst to frag. */
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ /* Control 810 not to generate jsri. */
+ if (IS_CSKY_ARCH_810 (mach_flag))
+ {
+ /* Look at adding the R_PCREL_JSRIMM26BY2.
+ For 'jbsr .L1', this reloc type's symbol
+ is bound to '.L1', isn't bound to literal pool. */
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &(litpool + (csky_insn.e1.X_add_number >> 2))->e, 1,
+ BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
+ csky_insn.output = frag_more (4);
+ dwarf2_emit_insn (0);
+ /* The opcode of "mov32 r0,r0". */
+ csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
+ /* The effect of this value is to check literal. */
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ csky_insn.max = 8;
+ }
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_movih (void)
+{
+ int rz = csky_insn.val[0];
+ csky_insn.output = frag_more (4);
+ csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 16);
+ if (csky_insn.e1.X_op == O_constant)
+ {
+ if (csky_insn.e1.X_unsigned == 1 && csky_insn.e1.X_add_number > 0xffff)
+ {
+ csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
+ return FALSE;
+ }
+ else if (csky_insn.e1.X_unsigned == 0 && csky_insn.e1.X_add_number < 0)
+ {
+ csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
+ return FALSE;
+ }
+ else
+ csky_insn.inst |= (csky_insn.e1.X_add_number & 0xffff);
+ }
+ else if (csky_insn.e1.X_op == O_right_shift
+ || (csky_insn.e1.X_op == O_symbol && insn_reloc != BFD_RELOC_NONE))
+ {
+ if (csky_insn.e1.X_op_symbol != 0
+ && csky_insn.e1.X_op_symbol->sy_value.X_op == O_constant
+ && 16 == csky_insn.e1.X_op_symbol->sy_value.X_add_number)
+ {
+ csky_insn.e1.X_op = O_symbol;
+ if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
+ insn_reloc = BFD_RELOC_CKCORE_GOT_HI16;
+ else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
+ insn_reloc = BFD_RELOC_CKCORE_PLT_HI16;
+ else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
+ insn_reloc = BFD_RELOC_CKCORE_GOTPC_HI16;
+ else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
+ insn_reloc = BFD_RELOC_CKCORE_GOTOFF_HI16;
+ else
+ insn_reloc = BFD_RELOC_CKCORE_ADDR_HI16;
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 0, insn_reloc);
+ }
+ else
+ {
+ void *arg = (void *)"the second operand must be \"SYMBOL >> 16\"";
+ csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
+ return FALSE;
+ }
+ }
+ csky_insn.isize = 4;
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+
+ return TRUE;
+}
+
+bfd_boolean
+v2_work_ori (void)
+{
+ int rz = csky_insn.val[0];
+ int rx = csky_insn.val[1];
+ csky_insn.output = frag_more (4);
+ csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 21) | (rx << 16);
+ if (csky_insn.e1.X_op == O_constant)
+ {
+ if (csky_insn.e1.X_add_number <= 0xffff
+ && csky_insn.e1.X_add_number >= 0)
+ csky_insn.inst |= csky_insn.e1.X_add_number;
+ else
+ {
+ csky_show_error (ERROR_IMM_OVERFLOW, 3, NULL, NULL);
+ return FALSE;
+ }
+ }
+ else if (csky_insn.e1.X_op == O_bit_and)
+ {
+ if (csky_insn.e1.X_op_symbol->sy_value.X_op == O_constant
+ && 0xffff == csky_insn.e1.X_op_symbol->sy_value.X_add_number)
+ {
+ csky_insn.e1.X_op = O_symbol;
+ if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
+ insn_reloc = BFD_RELOC_CKCORE_GOT_LO16;
+ else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
+ insn_reloc = BFD_RELOC_CKCORE_PLT_LO16;
+ else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
+ insn_reloc = BFD_RELOC_CKCORE_GOTPC_LO16;
+ else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
+ insn_reloc = BFD_RELOC_CKCORE_GOTOFF_LO16;
+ else
+ insn_reloc = BFD_RELOC_CKCORE_ADDR_LO16;
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 0, insn_reloc);
+ }
+ else
+ {
+ void *arg = (void *)"the third operand must be \"SYMBOL & 0xffff\"";
+ csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
+ return FALSE;
+ }
+ }
+ csky_insn.isize = 4;
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+/* Helper function to encode a single/double floating point constant
+ into the instruction word for fmovis and fmovid instructions.
+ The constant is in its IEEE single/double precision representation
+ and is repacked into the internal 13-bit representation for these
+ instructions with a diagnostic for overflow. Note that there is no
+ rounding when converting to the smaller format, just an error if there
+ is excess precision or the number is too small/large to be represented. */
+
+bfd_boolean
+float_work_fmovi (void)
+{
+ int rx = csky_insn.val[0];
+
+ /* We already converted the float constant to the internal 13-bit
+ representation so we just need to OR it in here. */
+ csky_insn.inst = csky_insn.opcode->op32[0].opcode | rx;
+ csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
+
+ csky_insn.output = frag_more (4);
+ csky_insn.isize = 4;
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+bfd_boolean
+dsp_work_bloop (void)
+{
+ int reg = csky_insn.val[0];
+ csky_insn.output = frag_more (4);
+ csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
+ csky_insn.isize = 4;
+
+ if (csky_insn.e1.X_op == O_symbol
+ && csky_insn.e2.X_op == O_symbol)
+ {
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e1, 1,
+ BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
+ fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
+ 4, &csky_insn.e2, 1,
+ BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4);
+ }
+
+ csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
+ return TRUE;
+}
+
+
+/* The following are for assembler directive handling. */
+
+/* Helper function to adjust constant pool counts when we emit a
+ data directive in the text section. FUNC is one of the standard
+ gas functions to handle these directives, like "stringer" for the
+ .string directive, and ARG is the argument to FUNC. csky_pool_count
+ essentially wraps the call with the constant pool magic. */
+
+static void
+csky_pool_count (void (*func) (int), int arg)
+{
+ const fragS *curr_frag = frag_now;
+ offsetT added = -frag_now_fix_octets ();
+
+ (*func) (arg);
+
+ while (curr_frag != frag_now)
+ {
+ added += curr_frag->fr_fix;
+ curr_frag = curr_frag->fr_next;
+ }
+
+ added += frag_now_fix_octets ();
+ poolspan += added;
+}
+
+/* Support the .literals directive. */
+static void
+csky_s_literals (int ignore ATTRIBUTE_UNUSED)
+{
+ dump_literals (0);
+ demand_empty_rest_of_line ();
+}
+
+/* Support the .string, etc directives. */
+static void
+csky_stringer (int append_zero)
+{
+ if (now_seg == text_section)
+ csky_pool_count (stringer, append_zero);
+ else
+ stringer (append_zero);
+
+ /* We call check_literals here in case a large number of strings are
+ being placed into the text section with a sequence of stringer
+ directives. In theory we could be upsetting something if these
+ strings are actually in an indexed table instead of referenced by
+ individual labels. Let us hope that that never happens. */
+ check_literals (2, 0);
+}
+
+/* Support integer-mode constructors like .word, .byte, etc. */
+
+static void
+csky_cons (int nbytes)
+{
+ mapping_state (MAP_DATA);
+ if (nbytes == 4) /* @GOT. */
+ {
+ do
+ {
+ bfd_reloc_code_real_type reloc;
+ expressionS exp;
+
+ reloc = BFD_RELOC_NONE;
+ expression (&exp);
+ lex_got (&reloc, NULL);
+
+ if (exp.X_op == O_symbol && reloc != BFD_RELOC_NONE)
+ {
+ reloc_howto_type *howto
+ = bfd_reloc_type_lookup (stdoutput, reloc);
+ int size = bfd_get_reloc_size (howto);
+
+ if (size > nbytes)
+ as_bad (ngettext ("%s relocations do not fit in %d byte",
+ "%s relocations do not fit in %d bytes",
+ nbytes),
+ howto->name, nbytes);
+ else
+ {
+ register char *p = frag_more ((int) nbytes);
+ int offset = nbytes - size;
+
+ fix_new_exp (frag_now,
+ p - frag_now->fr_literal + offset,
+ size, &exp, 0, reloc);
+ }
+ }
+ else
+ emit_expr (&exp, (unsigned int) nbytes);
+ if (now_seg == text_section)
+ poolspan += nbytes;
+ }
+ while (*input_line_pointer++ == ',');
+
+ /* Put terminator back into stream. */
+ input_line_pointer --;
+ demand_empty_rest_of_line ();
+
+ return;
+ }
+
+ if (now_seg == text_section)
+ csky_pool_count (cons, nbytes);
+ else
+ cons (nbytes);
+
+ /* In theory we ought to call check_literals (2,0) here in case
+ we need to dump the literal table. We cannot do this however,
+ as the directives that we are intercepting may be being used
+ to build a switch table, and we must not interfere with its
+ contents. Instead we cross our fingers and pray... */
+}
+
+/* Support floating-mode constant directives like .float and .double. */
+
+static void
+csky_float_cons (int float_type)
+{
+ mapping_state (MAP_DATA);
+ if (now_seg == text_section)
+ csky_pool_count (float_cons, float_type);
+ else
+ float_cons (float_type);
+
+ /* See the comment in csky_cons () about calling check_literals.
+ It is unlikely that a switch table will be constructed using
+ floating point values, but it is still likely that an indexed
+ table of floating point constants is being created by these
+ directives, so again we must not interfere with their placement. */
+}
+
+/* Support the .fill directive. */
+
+static void
+csky_fill (int ignore)
+{
+ if (now_seg == text_section)
+ csky_pool_count (s_fill, ignore);
+ else
+ s_fill (ignore);
+
+ check_literals (2, 0);
+}
+
+/* Handle the section changing pseudo-ops. These call through to the
+ normal implementations, but they dump the literal pool first. */
+
+static void
+csky_s_text (int ignore)
+{
+ dump_literals (0);
+
+#ifdef OBJ_ELF
+ obj_elf_text (ignore);
+#else
+ s_text (ignore);
+#endif
+}
+
+static void
+csky_s_data (int ignore)
+{
+ dump_literals (0);
+
+#ifdef OBJ_ELF
+ obj_elf_data (ignore);
+#else
+ s_data (ignore);
+#endif
+}
+
+static void
+csky_s_section (int ignore)
+{
+ /* Scan forwards to find the name of the section. If the section
+ being switched to is ".line" then this is a DWARF1 debug section
+ which is arbitrarily placed inside generated code. In this case
+ do not dump the literal pool because it is a) inefficient and
+ b) would require the generation of extra code to jump around the
+ pool. */
+ char * ilp = input_line_pointer;
+
+ while (*ilp != 0 && ISSPACE (*ilp))
+ ++ ilp;
+
+ if (strncmp (ilp, ".line", 5) == 0
+ && (ISSPACE (ilp[5]) || *ilp == '\n' || *ilp == '\r'))
+ ;
+ else
+ dump_literals (0);
+
+#ifdef OBJ_ELF
+ obj_elf_section (ignore);
+#endif
+#ifdef OBJ_COFF
+ obj_coff_section (ignore);
+#endif
+}
+
+static void
+csky_s_bss (int needs_align)
+{
+ dump_literals (0);
+ s_lcomm_bytes (needs_align);
+}
+
+#ifdef OBJ_ELF
+static void
+csky_s_comm (int needs_align)
+{
+ dump_literals (0);
+ obj_elf_common (needs_align);
+}
+#endif
+
+/* Handle the .no_literal_dump directive. */
+
+static void
+csky_noliteraldump (int ignore ATTRIBUTE_UNUSED)
+{
+ do_noliteraldump = 1;
+ int insn_num = get_absolute_expression ();
+ /* The insn after '.no_literal_dump insn_num' is insn1,
+ Don't dump literal pool between insn1 and insn(insn_num+1)
+ The insn cannot be the insn generate literal, like lrw & jsri. */
+ check_literals (0, insn_num * 2);
+}
+
+/* Handle the .align directive.
+ We must check literals before doing alignment. For example, if
+ '.align n', add (2^n-1) to poolspan and check literals. */
+
+static void
+csky_s_align_ptwo (int arg)
+{
+ /* Get the .align's first absolute number. */
+ char * temp_pointer = input_line_pointer;
+ int align = get_absolute_expression ();
+ check_literals (0, (1 << align) - 1);
+ input_line_pointer = temp_pointer;
+
+ /* Do alignment. */
+ s_align_ptwo (arg);
+}
+
+/* Handle the .stack_size directive. */
+
+static void
+csky_stack_size (int arg ATTRIBUTE_UNUSED)
+{
+ expressionS exp;
+ stack_size_entry *sse
+ = (stack_size_entry *) xcalloc (1, sizeof (stack_size_entry));
+
+ expression (&exp);
+ if (exp.X_op == O_symbol)
+ sse->function = exp.X_add_symbol;
+ else
+ {
+ as_bad (_("the first operand must be a symbol"));
+ ignore_rest_of_line ();
+ free (sse);
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing stack size"));
+ ignore_rest_of_line ();
+ free (sse);
+ return;
+ }
+
+ ++input_line_pointer;
+ expression (&exp);
+ if (exp.X_op == O_constant)
+ {
+ if (exp.X_add_number < 0 || exp.X_add_number > (offsetT)0xffffffff)
+ {
+
+ as_bad (_("value not in range [0, 0xffffffff]"));
+ ignore_rest_of_line ();
+ free (sse);
+ return;
+ }
+ else
+ sse->stack_size = exp.X_add_number;
+ }
+ else
+ {
+ as_bad (_("operand must be a constant"));
+ ignore_rest_of_line ();
+ free (sse);
+ return;
+ }
+
+ if (*last_stack_size_data != NULL)
+ last_stack_size_data = &((*last_stack_size_data)->next);
+
+ *last_stack_size_data = sse;
+}
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function. */
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "export", s_globl, 0 },
+ { "import", s_ignore, 0 },
+ { "literals", csky_s_literals, 0 },
+ { "page", listing_eject, 0 },
+
+ /* The following are to intercept the placement of data into the text
+ section (eg addresses for a switch table), so that the space they
+ occupy can be taken into account when deciding whether or not to
+ dump the current literal pool.
+ XXX - currently we do not cope with the .space and .dcb.d directives. */
+ { "ascii", csky_stringer, 8 + 0 },
+ { "asciz", csky_stringer, 8 + 1 },
+ { "byte", csky_cons, 1 },
+ { "dc", csky_cons, 2 },
+ { "dc.b", csky_cons, 1 },
+ { "dc.d", csky_float_cons, 'd'},
+ { "dc.l", csky_cons, 4 },
+ { "dc.s", csky_float_cons, 'f'},
+ { "dc.w", csky_cons, 2 },
+ { "dc.x", csky_float_cons, 'x'},
+ { "double", csky_float_cons, 'd'},
+ { "float", csky_float_cons, 'f'},
+ { "hword", csky_cons, 2 },
+ { "int", csky_cons, 4 },
+ { "long", csky_cons, 4 },
+ { "octa", csky_cons, 16 },
+ { "quad", csky_cons, 8 },
+ { "short", csky_cons, 2 },
+ { "single", csky_float_cons, 'f'},
+ { "string", csky_stringer, 8 + 1 },
+ { "word", csky_cons, 4 },
+ { "fill", csky_fill, 0 },
+
+ /* Allow for the effect of section changes. */
+ { "text", csky_s_text, 0 },
+ { "data", csky_s_data, 0 },
+ { "bss", csky_s_bss, 1 },
+#ifdef OBJ_ELF
+ { "comm", csky_s_comm, 0 },
+#endif
+ { "section", csky_s_section, 0 },
+ { "section.s", csky_s_section, 0 },
+ { "sect", csky_s_section, 0 },
+ { "sect.s", csky_s_section, 0 },
+ /* When ".no_literal_dump N" is in front of insn1,
+ and instruction sequence is:
+ insn1
+ insn2
+ ......
+ insnN+1
+ it means literals will not dump between insn1 and insnN+1
+ The insn cannot itself generate literal, like lrw & jsri. */
+ { "no_literal_dump", csky_noliteraldump, 0 },
+ { "align", csky_s_align_ptwo, 0 },
+ { "stack_size", csky_stack_size, 0 },
+ {0, 0, 0}
+};
+
+/* Implement tc_cfi_frame_initial_instructions. */
+
+void
+csky_cfi_frame_initial_instructions (void)
+{
+ int sp_reg = IS_CSKY_V1 (mach_flag) ? 0 : 14;
+ cfi_add_CFA_def_cfa_register (sp_reg);
+}
+
+/* Implement tc_regname_to_dw2regnum. */
+
+int
+tc_csky_regname_to_dw2regnum (char *regname)
+{
+ int reg_num = -1;
+ int len;
+
+ /* FIXME the reg should be parsed according to
+ the abi version. */
+ reg_num = csky_get_reg_val (regname, &len);
+ return reg_num;
+}
diff --git a/gas/config/tc-csky.h b/gas/config/tc-csky.h
new file mode 100644
index 0000000..4ea0c03
--- /dev/null
+++ b/gas/config/tc-csky.h
@@ -0,0 +1,107 @@
+/* tc-csky.h -- Header file for tc-csky.c
+ Copyright (C) 1989-2018 Free Software Foundation, Inc.
+ Contributed by C-SKY Microsystems and Mentor Graphics.
+
+ 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef TC_CSKY
+#define TC_CSKY 1
+
+#define WORKING_DOT_WORD
+
+#define TARGET_ARCH bfd_arch_csky
+
+#define LISTING_HEADER "CSKY GAS"
+
+#ifdef OBJ_ELF
+#define TARGET_FORMAT elf32_csky_target_format ()
+#endif
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define MD_PCREL_FROM_SECTION(F,S) md_pcrel_from_section (F, S)
+
+#define TC_GENERIC_RELAX_TABLE csky_relax_table
+
+#define md_end md_csky_end
+#define md_relax_frag csky_relax_frag
+#define DOUBLESLASH_LINE_COMMENTS
+#define LOCAL_LABELS_FB 1
+#define PAD_LITERAL_LENGTH 6
+#define PAD_FILL_CONTENT 0x1c00
+
+/* Reloc API. */
+#define EXTERN_FORCE_RELOC 1
+#define TC_CONS_FIX_NEW csky_cons_fix_new
+#define TC_FORCE_RELOCATION(fix) csky_force_relocation (fix)
+#define tc_fix_adjustable(FIX) csky_fix_adjustable (FIX)
+#define TC_SEGMENT_INFO_TYPE csky_segment_info_type
+
+/* Dwarf API. */
+#define DWARF2_LINE_MIN_INSN_LENGTH 2
+#define DWARF2_ADDR_SIZE(bfd) 4
+#define DWARF2_FDE_RELOC_SIZE 4
+#define TARGET_USE_CFIPOP 1
+#define tc_cfi_frame_initial_instructions csky_cfi_frame_initial_instructions
+#define tc_regname_to_dw2regnum tc_csky_regname_to_dw2regnum
+#define DWARF2_DEFAULT_RETURN_COLUMN 15
+#define DWARF2_CIE_DATA_ALIGNMENT (-4)
+
+typedef enum
+{
+ MAP_UNDEFINED = 0,
+ MAP_DATA,
+ MAP_TEXT,
+} map_state;
+
+typedef struct
+{
+ map_state current_state;
+} csky_segment_info_type;
+
+struct tls_addend
+{
+ fragS *frag;
+ offsetT offset;
+};
+
+#define TC_FIX_TYPE struct tls_addend
+#define TC_INIT_FIX_DATA(FIX) \
+ { (FIX)->tc_fix_data.frag = NULL; (FIX)->tc_fix_data.offset = 0; }
+
+#include "write.h"
+extern const relax_typeS csky_relax_table [];
+
+extern void md_csky_end (void);
+extern long md_pcrel_from_section (fixS *, segT);
+extern void csky_cons_fix_new (fragS *,
+ unsigned int off,
+ unsigned int len,
+ expressionS *,
+ bfd_reloc_code_real_type);
+extern int csky_force_relocation (fixS *);
+extern bfd_boolean csky_fix_adjustable (fixS *);
+extern void csky_cfi_frame_initial_instructions (void);
+extern int tc_csky_regname_to_dw2regnum (char *);
+extern long csky_relax_frag (segT, fragS *, long);
+
+#ifdef OBJ_ELF
+const char * elf32_csky_target_format (void);
+#endif
+
+#endif
diff --git a/gas/config/te-csky_abiv1.h b/gas/config/te-csky_abiv1.h
new file mode 100644
index 0000000..5185abc
--- /dev/null
+++ b/gas/config/te-csky_abiv1.h
@@ -0,0 +1,24 @@
+/* Environment definitions for C-SKY ABIV2 bare-metal targets.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ Contributed by C-SKY Microsystems and Mentor Graphics.
+
+ 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "obj-format.h"
+
+#define _CSKY_ABI 1
diff --git a/gas/config/te-csky_abiv1_linux.h b/gas/config/te-csky_abiv1_linux.h
new file mode 100644
index 0000000..1999bf7
--- /dev/null
+++ b/gas/config/te-csky_abiv1_linux.h
@@ -0,0 +1,24 @@
+/* Environment definitions for C-SKY ABIV1 Linux targets.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ Contributed by C-SKY Microsystems and Mentor Graphics.
+
+ 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "obj-format.h"
+
+#define _CSKY_ABI 1
diff --git a/gas/config/te-csky_abiv2.h b/gas/config/te-csky_abiv2.h
new file mode 100644
index 0000000..c0b649d
--- /dev/null
+++ b/gas/config/te-csky_abiv2.h
@@ -0,0 +1,26 @@
+/* Environment definitions for C-SKY ABIV2 bare-metal targets.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ Contributed by C-SKY Microsystems and Mentor Graphics.
+
+ 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#define INCLUDE_BRANCH_STUB
+
+#include "obj-format.h"
+
+#define _CSKY_ABI 2
diff --git a/gas/config/te-csky_abiv2_linux.h b/gas/config/te-csky_abiv2_linux.h
new file mode 100644
index 0000000..06854f3
--- /dev/null
+++ b/gas/config/te-csky_abiv2_linux.h
@@ -0,0 +1,24 @@
+/* Environment definitions for C-SKY ABIV2 Linux targets.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ Contributed by C-SKY Microsystems and Mentor Graphics.
+
+ 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "obj-format.h"
+
+#define _CSKY_ABI 2
diff --git a/gas/configure.tgt b/gas/configure.tgt
index 6df7dea..d1b0535 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -173,6 +173,11 @@ case ${generic_target} in
crx-*-elf*) fmt=elf ;;
+ csky-*-elf*abiv1) fmt=elf em=csky_abiv1 ;;
+ csky-*-elf*) fmt=elf em=csky_abiv2 ;;
+ csky-*-linux*abiv1) fmt=elf em=csky_abiv1_linux ;;
+ csky-*-linux*) fmt=elf em=csky_abiv2_linux ;;
+
d10v-*-*) fmt=elf ;;
d30v-*-*) fmt=elf ;;
dlx-*-*) fmt=elf ;;
@@ -431,7 +436,7 @@ case ${generic_target} in
esac
case ${cpu_type} in
- aarch64 | alpha | arm | i386 | ia64 | microblaze | mips | ns32k | or1k | or1knd | pdp11 | ppc | riscv | sparc | z80 | z8k)
+ aarch64 | alpha | arm | csky | i386 | ia64 | microblaze | mips | ns32k | or1k | or1knd | pdp11 | ppc | riscv | sparc | z80 | z8k)
bfd_gas=yes
;;
esac
diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am
index b3d4fa7..210f2e4 100644
--- a/gas/doc/Makefile.am
+++ b/gas/doc/Makefile.am
@@ -54,6 +54,7 @@ CPU_DOCS = \
c-bfin.texi \
c-cr16.texi \
c-cris.texi \
+ c-csky.texi \
c-d10v.texi \
c-epiphany.texi \
c-h8300.texi \
diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in
index b745b7e..765e6b0 100644
--- a/gas/doc/Makefile.in
+++ b/gas/doc/Makefile.in
@@ -409,6 +409,7 @@ CPU_DOCS = \
c-bfin.texi \
c-cr16.texi \
c-cris.texi \
+ c-csky.texi \
c-d10v.texi \
c-epiphany.texi \
c-h8300.texi \
diff --git a/gas/doc/all.texi b/gas/doc/all.texi
index 2b8af69..ef103de 100644
--- a/gas/doc/all.texi
+++ b/gas/doc/all.texi
@@ -32,6 +32,7 @@
@set Blackfin
@set CR16
@set CRIS
+@set CSKY
@set D10V
@set D30V
@set EPIPHANY
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index aea5e71..be84bf2 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -306,6 +306,26 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
@c Deprecated -- deliberately not documented.
@c [@b{-h}] [@b{-H}]
@end ifset
+@ifset CSKY
+
+@emph{Target C-SKY options:}
+ [@b{-march=@var{arch}}] [@b{-mcpu=@var{cpu}}]
+ [@b{-EL}] [@b{-mlittle-endian}] [@b{-EB}] [@b{-mbig-endian}]
+ [@b{-fpic}] [@b{-pic}]
+ [@b{-mljump}] [@b{-mno-ljump}]
+ [@b{-force2bsr}] [@b{-mforce2bsr}] [@b{-no-force2bsr}] [@b{-mno-force2bsr}]
+ [@b{-jsri2bsr}] [@b{-mjsri2bsr}] [@b{-no-jsri2bsr }] [@b{-mno-jsri2bsr}]
+ [@b{-mnolrw }] [@b{-mno-lrw}]
+ [@b{-melrw}] [@b{-mno-elrw}]
+ [@b{-mlaf }] [@b{-mliterals-after-func}]
+ [@b{-mno-laf}] [@b{-mno-literals-after-func}]
+ [@b{-mlabr}] [@b{-mliterals-after-br}]
+ [@b{-mno-labr}] [@b{-mnoliterals-after-br}]
+ [@b{-mistack}] [@b{-mno-istack}]
+ [@b{-mhard-float}] [@b{-mmp}] [@b{-mcp}] [@b{-mcache}]
+ [@b{-msecurity}] [@b{-mtrust}]
+ [@b{-mdsp}] [@b{-medsp}] [@b{-mvdsp}]
+@end ifset
@ifset D10V
@emph{Target D10V options:}
@@ -979,6 +999,25 @@ the Blackfin processor family.
See the info pages for documentation of the CRIS-specific options.
@end ifset
+@ifset CSKY
+
+@ifclear man
+@xref{C-SKY Options}, for the options available when @value{AS} is
+configured for the C-SKY processor family.
+@end ifclear
+
+@ifset man
+@c man begin OPTIONS
+The following options are available when @value{AS} is configured for
+the C-SKY processor family.
+@c man end
+@c man begin INCLUDE
+@include c-csky.texi
+@c ended inside the included file
+@end ifset
+
+@end ifset
+
@ifset D10V
The following options are available when @value{AS} is configured for
a D10V processor.
@@ -7548,6 +7587,9 @@ subject, see the hardware manufacturer's manual.
@ifset CRIS
* CRIS-Dependent:: CRIS Dependent Features
@end ifset
+@ifset CSKY
+* C-SKY-Dependent:: C-SKY Dependent Features
+@end ifset
@ifset D10V
* D10V-Dependent:: D10V Dependent Features
@end ifset
@@ -7731,6 +7773,10 @@ subject, see the hardware manufacturer's manual.
@include c-cris.texi
@end ifset
+@ifset CSKY
+@include c-csky.texi
+@end ifset
+
@ifset Renesas-all
@ifclear GENERIC
@node Machine Dependencies
diff --git a/gas/doc/c-csky.texi b/gas/doc/c-csky.texi
new file mode 100644
index 0000000..5087de9
--- /dev/null
+++ b/gas/doc/c-csky.texi
@@ -0,0 +1,195 @@
+@c Copyright (C) 2012-2018 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@c man end
+@ifset GENERIC
+@page
+@node C-SKY-Dependent
+@chapter C-SKY Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter C-SKY Dependent Features
+@end ifclear
+
+@cindex C-SKY support
+@menu
+* C-SKY Options:: Options
+* C-SKY Syntax:: Syntax
+@end menu
+
+@node C-SKY Options
+@section Options
+@cindex C-SKY options
+@cindex options for C-SKY
+
+@c man begin OPTIONS
+@table @gcctabopt
+
+@cindex @code{march} command-line option, C-SKY
+@item -march=@var{archname}
+Assemble for architecture @var{archname}. The @option{--help} option
+lists valid values for @var{archname}.
+
+@cindex @code{mcpu} command-line option, C-SKY
+@item -mcpu=@var{cpuname}
+Assemble for architecture @var{cpuname}. The @option{--help} option
+lists valid values for @var{cpuname}.
+
+@cindex @code{EL} command-line option, C-SKY
+@cindex @code{mlittle-endian} command-line option, C-SKY
+@item -EL
+@itemx -mlittle-endian
+Generate little-endian output.
+
+@cindex @code{EB} command-line option, C-SKY
+@cindex @code{mbig-endian} command-line option, C-SKY
+@item -EB
+@itemx -mbig-endian
+Generate big-endian output.
+
+@cindex @code{fpic} command-line option, C-SKY
+@cindex @code{pic} command-line option, C-SKY
+@item -fpic
+@itemx -pic
+Generate position-independent code.
+
+@cindex @code{mljump} command-line option, C-SKY
+@cindex @code{mno-ljump} command-line option, C-SKY
+@item -mljump
+@itemx -mno-ljump
+Enable/disable transformation of the short branch instructions
+@code{jbf}, @code{jbt}, and @code{jbr} to @code{jmpi}.
+This option is for V2 processors only.
+It is ignored on CK801 and CK802 targets, which do not support the @code{jmpi}
+instruction, and is enabled by default for other processors.
+
+@cindex @code{mbranch-stub} command-line option, C-SKY
+@cindex @code{mno-branch-stub} command-line option, C-SKY
+@item -mbranch-stub
+@itemx -mno-branch-stub
+Pass through @code{R_CKCORE_PCREL_IMM26BY2} relocations for @code{bsr}
+instructions to the linker.
+
+This option is only available for bare-metal C-SKY V2 ELF targets,
+where it is enabled by default. It cannot be used in code that will be
+dynamically linked against shared libraries.
+
+@cindex @code{force2bsr} command-line option, C-SKY
+@cindex @code{mforce2bsr} command-line option, C-SKY
+@cindex @code{no-force2bsr} command-line option, C-SKY
+@cindex @code{mno-force2bsr} command-line option, C-SKY
+@item -force2bsr
+@itemx -mforce2bsr
+@itemx -no-force2bsr
+@itemx -mno-force2bsr
+Enable/disable transformation of @code{jbsr} instructions to @code{bsr}.
+This option is always enabled (and @option{-mno-force2bsr} is ignored)
+for CK801/CK802 targets. It is also always enabled when
+@option{-mbranch-stub} is in effect.
+
+@cindex @code{jsri2bsr} command-line option, C-SKY
+@cindex @code{mjsri2bsr} command-line option, C-SKY
+@cindex @code{no-jsri2bsr} command-line option, C-SKY
+@cindex @code{mno-jsri2bsr} command-line option, C-SKY
+@item -jsri2bsr
+@itemx -mjsri2bsr
+@itemx -no-jsri2bsr
+@itemx -mno-jsri2bsr
+Enable/disable transformation of @code{jsri} instructions to @code{bsr}.
+This option is enabled by default.
+
+@cindex @code{mnolrw} command-line option, C-SKY
+@cindex @code{mno-lrw} command-line option, C-SKY
+@item -mnolrw
+@itemx -mno-lrw
+Enable/disable transformation of @code{lrw} instructions into a
+@code{movih}/@code{ori} pair.
+
+@cindex @code{melrw} command-line option, C-SKY
+@cindex @code{mno-elrw} command-line option, C-SKY
+@item -melrw
+@itemx -mno-elrw
+Enable/disable extended @code{lrw} instructions.
+This option is enabled by default for CK800-series processors.
+
+@cindex @code{mlaf} command-line option, C-SKY
+@cindex @code{mliterals-after-func} command-line option, C-SKY
+@cindex @code{mno-laf} command-line option, C-SKY
+@cindex @code{mno-literals-after-func} command-line option, C-SKY
+@item -mlaf
+@itemx -mliterals-after-func
+@itemx -mno-laf
+@itemx -mno-literals-after-func
+Enable/disable placement of literal pools after each function.
+
+@cindex @code{mlabr} command-line option, C-SKY
+@cindex @code{mliterals-after-br} command-line option, C-SKY
+@cindex @code{mno-labr} command-line option, C-SKY
+@cindex @code{mnoliterals-after-br} command-line option, C-SKY
+@item -mlabr
+@itemx -mliterals-after-br
+@itemx -mno-labr
+@itemx -mnoliterals-after-br
+Enable/disable placement of literal pools after unconditional branches.
+This option is enabled by default.
+
+@cindex @code{mistack} command-line option, C-SKY
+@cindex @code{mno-istack} command-line option, C-SKY
+@item -mistack
+@itemx -mno-istack
+Enable/disable interrupt stack instructions. This option is enabled by
+default on CK801, CK802, and CK802 processors.
+
+@end table
+
+The following options explicitly enable certain optional instructions.
+These features are also enabled implicitly by using @code{-mcpu=} to specify
+a processor that supports it.
+
+@table @gcctabopt
+@cindex @code{mhard-float} command-line option, C-SKY
+@item -mhard-float
+Enable hard float instructions.
+
+@cindex @code{mmp} command-line option, C-SKY
+@item -mmp
+Enable multiprocessor instructions.
+
+@cindex @code{mcp} command-line option, C-SKY
+@item -mcp
+Enable coprocessor instructions.
+
+@cindex @code{mcache} command-line option, C-SKY
+@item -mcache
+Enable cache prefetch instruction.
+
+@cindex @code{msecurity} command-line option, C-SKY
+@item -msecurity
+Enable C-SKY security instructions.
+
+@cindex @code{mtrust} command-line option, C-SKY
+@item -mtrust
+Enable C-SKY trust instructions.
+
+@cindex @code{mdsp} command-line option, C-SKY
+@item -mdsp
+Enable DSP instructions.
+
+@cindex @code{medsp} command-line option, C-SKY
+@item -medsp
+Enable enhanced DSP instructions.
+
+@cindex @code{mvdsp} command-line option, C-SKY
+@item -mvdsp
+Enable vector DSP instructions.
+
+@end table
+@c man end
+
+@node C-SKY Syntax
+@section Syntax
+
+@code{@value{AS}} implements the standard C-SKY assembler syntax
+documented in the
+@cite{C-SKY V2 CPU Applications Binary Interface Standards Manual}.
diff --git a/gas/testsuite/gas/csky/801_relax.d b/gas/testsuite/gas/csky/801_relax.d
new file mode 100644
index 0000000..1677fb1
--- /dev/null
+++ b/gas/testsuite/gas/csky/801_relax.d
@@ -0,0 +1,14 @@
+#name: csky - 801_relax
+#as: -march=ck801
+#objdump: -d
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*2:\s*0803\s*bt\s*0x8\s*.*
+\s*4:\s*e800025c\s*br\s*0x4bc\s*.*
+#...
+\s*4bc:\s*0c03\s*bf\s*0x4c2\s*.*
+\s*4be:\s*e800fda2\s*br\s*0x2\s*.*
+#...
diff --git a/gas/testsuite/gas/csky/801_relax.s b/gas/testsuite/gas/csky/801_relax.s
new file mode 100644
index 0000000..56a7421
--- /dev/null
+++ b/gas/testsuite/gas/csky/801_relax.s
@@ -0,0 +1,16 @@
+# Test ck801 jbf/jbt branch relaxation.
+
+ addu a1, a2, a3
+.L1:
+ jbf .L2
+ addu a3, a2, a1
+
+ .rept 600
+ nop
+ .endr
+
+
+ addu a1, a2, a3
+.L2:
+ jbt .L1
+ addu a3, a2, a1
diff --git a/gas/testsuite/gas/csky/802j.d b/gas/testsuite/gas/csky/802j.d
new file mode 100644
index 0000000..af7c857
--- /dev/null
+++ b/gas/testsuite/gas/csky/802j.d
@@ -0,0 +1,13 @@
+# name: csky - 802j
+#as: -mcpu=ck802j -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*1463\s*ipop
+\s*[0-9a-f]*:\s*1462\s*ipush
+\s*[0-9a-f]*:\s*1460\s*nie
+\s*[0-9a-f]*:\s*1461\s*nir
+\s*[0-9a-f]*:\s*3ae0\s*jmpix\s*r2,\s*16.*
diff --git a/gas/testsuite/gas/csky/802j.s b/gas/testsuite/gas/csky/802j.s
new file mode 100644
index 0000000..852cd2c
--- /dev/null
+++ b/gas/testsuite/gas/csky/802j.s
@@ -0,0 +1,7 @@
+.text
+all:
+ ipop
+ ipush
+ nie
+ nir
+ jmpix r2, 16
diff --git a/gas/testsuite/gas/csky/all.d b/gas/testsuite/gas/csky/all.d
new file mode 100644
index 0000000..c5da5b0
--- /dev/null
+++ b/gas/testsuite/gas/csky/all.d
@@ -0,0 +1,150 @@
+# name: csky - all
+#as: -mcpu=ck610e -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*0000\s*bkpt
+\s*[0-9a-f]*:\s*0001\s*sync
+\s*[0-9a-f]*:\s*0002\s*rte
+\s*[0-9a-f]*:\s*0002\s*rte
+\s*[0-9a-f]*:\s*0003\s*rfi
+\s*[0-9a-f]*:\s*0004\s*stop
+\s*[0-9a-f]*:\s*0005\s*wait
+\s*[0-9a-f]*:\s*0006\s*doze
+\s*[0-9a-f]*:\s*0007\s*idly4
+\s*[0-9a-f]*:\s*000b\s*trap\s*3
+\s*[0-9a-f]*:\s*0021\s*mvc\s*r1
+\s*[0-9a-f]*:\s*0032\s*mvcv\s*r2
+\s*[0-9a-f]*:\s*0042\s*ldq\s*r4-r7, \(r2\)
+\s*[0-9a-f]*:\s*0052\s*stq\s*r4-r7, \(r2\)
+\s*[0-9a-f]*:\s*0061\s*ldm\s*r1-r15, \(sp\)
+\s*[0-9a-f]*:\s*0082\s*dect\s*r2, r2, 1
+\s*[0-9a-f]*:\s*0092\s*decf\s*r2, r2, 1
+\s*[0-9a-f]*:\s*00a2\s*inct\s*r2, r2, 1
+\s*[0-9a-f]*:\s*00b2\s*incf\s*r2, r2, 1
+\s*[0-9a-f]*:\s*00c1\s*jmp\s*r1
+\s*[0-9a-f]*:\s*00d1\s*jsr\s*r1
+\s*[0-9a-f]*:\s*00eb\s*ff1\s*r11, r11
+\s*[0-9a-f]*:\s*00f1\s*brev\s*r1, r1
+\s*[0-9a-f]*:\s*0102\s*xtrb3\s*r1, r2
+\s*[0-9a-f]*:\s*0112\s*xtrb2\s*r1, r2
+\s*[0-9a-f]*:\s*0122\s*xtrb1\s*r1, r2
+\s*[0-9a-f]*:\s*0132\s*xtrb0\s*r1, r2
+\s*[0-9a-f]*:\s*0132\s*xtrb0\s*r1, r2
+\s*[0-9a-f]*:\s*0132\s*xtrb0\s*r1, r2
+\s*[0-9a-f]*:\s*1213\s*mov\s*r3, r1
+\s*[0-9a-f]*:\s*0142\s*zextb\s*r2, r2
+\s*[0-9a-f]*:\s*0152\s*sextb\s*r2, r2
+\s*[0-9a-f]*:\s*0162\s*zexth\s*r2, r2
+\s*[0-9a-f]*:\s*0172\s*sexth\s*r2, r2
+\s*[0-9a-f]*:\s*0182\s*declt\s*r2, r2, 1
+\s*[0-9a-f]*:\s*01b1\s*decne\s*r1, r1, 1
+\s*[0-9a-f]*:\s*01a1\s*decgt\s*r1, r1, 1
+\s*[0-9a-f]*:\s*01c1\s*clrt\s*r1
+\s*[0-9a-f]*:\s*01d1\s*clrf\s*r1
+\s*[0-9a-f]*:\s*01e3\s*abs\s*r3, r3
+\s*[0-9a-f]*:\s*01fc\s*not\s*r12, r12
+\s*[0-9a-f]*:\s*0221\s*movt\s*r1, r2
+\s*[0-9a-f]*:\s*0343\s*mult\s*r3, r3, r4
+\s*[0-9a-f]*:\s*0587\s*subu\s*r7, r7, r8
+\s*[0-9a-f]*:\s*0587\s*subu\s*r7, r7, r8
+\s*[0-9a-f]*:\s*06a9\s*addc\s*r9, r9, r10
+\s*[0-9a-f]*:\s*07cb\s*subc\s*r11, r11, r12
+\s*[0-9a-f]*:\s*0adc\s*movf\s*r12, r13
+\s*[0-9a-f]*:\s*0bdc\s*lsr\s*r12, r12, r13
+\s*[0-9a-f]*:\s*0ced\s*cmphs\s*r13, r14
+\s*[0-9a-f]*:\s*0ded\s*cmplt\s*r13, r14
+\s*[0-9a-f]*:\s*0eed\s*tst\s*r13, r14
+\s*[0-9a-f]*:\s*0fed\s*cmpne\s*r13, r14
+\s*[0-9a-f]*:\s*11f7\s*psrclr\s*ie, fe, ee
+\s*[0-9a-f]*:\s*1253\s*mov\s*r3, r5
+\s*[0-9a-f]*:\s*1332\s*bgenr\s*r2, r3
+\s*[0-9a-f]*:\s*1643\s*and\s*r3, r3, r4
+\s*[0-9a-f]*:\s*1543\s*ixw\s*r3, r3, r4
+\s*[0-9a-f]*:\s*1a43\s*asr\s*r3, r3, r4
+\s*[0-9a-f]*:\s*1c43\s*addu\s*r3, r3, r4
+\s*[0-9a-f]*:\s*1d32\s*ixh\s*r2, r2, r3
+\s*[0-9a-f]*:\s*1f43\s*andn\s*r3, r3, r4
+\s*[0-9a-f]*:\s*21f3\s*addi\s*r3, r3, 32
+\s*[0-9a-f]*:\s*23f3\s*cmplti\s*r3, 32
+\s*[0-9a-f]*:\s*2413\s*subi\s*r3, r3, 2
+\s*[0-9a-f]*:\s*2823\s*rsubi\s*r3, r3, 2
+\s*[0-9a-f]*:\s*2a33\s*cmpnei\s*r3, 3
+\s*[0-9a-f]*:\s*2c83\s*bmaski\s*r3, 8
+\s*[0-9a-f]*:\s*2c13\s*divu\s*r3, r3, r1
+\s*[0-9a-f]*:\s*2c22\s*mflos\s*r2
+\s*[0-9a-f]*:\s*2c32\s*mfhis\s*r2
+\s*[0-9a-f]*:\s*2c42\s*mtlo\s*r2
+\s*[0-9a-f]*:\s*2c52\s*mthi\s*r2
+\s*[0-9a-f]*:\s*2c62\s*mflo\s*r2
+\s*[0-9a-f]*:\s*2c72\s*mfhi\s*r2
+\s*[0-9a-f]*:\s*2e33\s*andi\s*r3, r3, 3
+\s*[0-9a-f]*:\s*3033\s*bclri\s*r3, r3, 3
+\s*[0-9a-f]*:\s*3293\s*bgeni\s*r3, 9
+\s*[0-9a-f]*:\s*6403\s*movi\s*r3, 64
+\s*[0-9a-f]*:\s*3213\s*divs\s*r3, r3, r1
+\s*[0-9a-f]*:\s*1221\s*mov\s*r1, r2
+\s*[0-9a-f]*:\s*3213\s*divs\s*r3, r3, r1
+\s*[0-9a-f]*:\s*3493\s*bseti\s*r3, r3, 9
+\s*[0-9a-f]*:\s*3693\s*btsti\s*r3, 9
+\s*[0-9a-f]*:\s*3803\s*xsr\s*r3, r3, 1
+\s*[0-9a-f]*:\s*3823\s*rotli\s*r3, r3, 2
+\s*[0-9a-f]*:\s*3a03\s*asrc\s*r3, r3, 1
+\s*[0-9a-f]*:\s*3a31\s*asri\s*r1, r1, 3
+\s*[0-9a-f]*:\s*67f7\s*movi\s*r7, 127
+\s*[0-9a-f]*:\s*8200\s*ld.w\s*r2,\s*\(r0,\s*0x0\)
+\s*[0-9a-f]*:\s*8210\s*ld.w\s*r2,\s*\(r0,\s*0x4\)
+\s*[0-9a-f]*:\s*8220\s*ld.w\s*r2,\s*\(r0,\s*0x8\)
+\s*[0-9a-f]*:\s*9200\s*st.w\s*r2,\s*\(r0,\s*0x0\)
+\s*[0-9a-f]*:\s*9210\s*st.w\s*r2,\s*\(r0,\s*0x4\)
+\s*[0-9a-f]*:\s*9220\s*st.w\s*r2,\s*\(r0,\s*0x8\)
+\s*[0-9a-f]*:\s*c210\s*ld.h\s*r2,\s*\(r0,\s*0x2\)
+\s*[0-9a-f]*:\s*c220\s*ld.h\s*r2,\s*\(r0,\s*0x4\)
+\s*[0-9a-f]*:\s*d210\s*st.h\s*r2,\s*\(r0,\s*0x2\)
+\s*[0-9a-f]*:\s*d220\s*st.h\s*r2,\s*\(r0,\s*0x4\)
+\s*[0-9a-f]*:\s*a200\s*ld.b\s*r2,\s*\(r0,\s*0x0\)
+\s*[0-9a-f]*:\s*a210\s*ld.b\s*r2,\s*\(r0,\s*0x1\)
+\s*[0-9a-f]*:\s*b200\s*st.b\s*r2,\s*\(r0,\s*0x0\)
+\s*[0-9a-f]*:\s*b210\s*st.b\s*r2,\s*\(r0,\s*0x1\)
+\s*[0-9a-f]*:\s*e798\s*bt\s*0x0.*
+\s*[0-9a-f]*:\s*ef97\s*bf\s*0x0.*
+\s*[0-9a-f]*:\s*f796\s*br\s*0x0.*
+\s*[0-9a-f]*:\s*0c00\s*cmphs\s*r0, r0
+\s*[0-9a-f]*:\s*0f00\s*cmpne\s*r0, r0
+\s*[0-9a-f]*:\s*2205\s*cmplti\s*r5, 1
+\s*[0-9a-f]*:\s*2263\s*cmplti\s*r3, 7
+\s*[0-9a-f]*:\s*2807\s*rsubi\s*r7, r7, 0
+\s*[0-9a-f]*:\s*2a06\s*cmpnei\s*r6, 0
+\s*[0-9a-f]*:\s*37f0\s*btsti\s*r0, 31
+\s*[0-9a-f]*:\s*31f3\s*bclri\s*r3, r3, 31
+\s*[0-9a-f]*:\s*6404\s*movi\s*r4, 64
+\s*[0-9a-f]*:\s*3274\s*bgeni\s*r4, 7
+\s*[0-9a-f]*:\s*3501\s*bseti\s*r1, r1, 16
+\s*[0-9a-f]*:\s*3644\s*btsti\s*r4, 4
+\s*[0-9a-f]*:\s*38c6\s*rotli\s*r6, r6, 12
+\s*[0-9a-f]*:\s*39f2\s*rotli\s*r2, r2, 31
+\s*[0-9a-f]*:\s*1200\s*mov\s*r0, r0
+\s*[0-9a-f]*:\s*0007\s*idly4
+\s*[0-9a-f]*:\s*0644\s*addc\s*r4, r4, r4
+\s*[0-9a-f]*:\s*0655\s*addc\s*r5, r5, r5
+\s*[0-9a-f]*:\s*0132\s*xtrb0\s*r1, r2
+\s*[0-9a-f]*:\s*0151\s*sextb\s*r1, r1
+\s*[0-9a-f]*:\s*0123\s*xtrb1\s*r1, r3
+\s*[0-9a-f]*:\s*0151\s*sextb\s*r1, r1
+\s*[0-9a-f]*:\s*0114\s*xtrb2\s*r1, r4
+\s*[0-9a-f]*:\s*0151\s*sextb\s*r1, r1
+\s*[0-9a-f]*:\s*0221\s*movt\s*r1, r2
+\s*[0-9a-f]*:\s*0a31\s*movf\s*r1, r3
+\s*[0-9a-f]*:\s*0d22\s*cmplt\s*r2, r2
+\s*[0-9a-f]*:\s*0672\s*addc\s*r2, r2, r7
+\s*[0-9a-f]*:\s*0683\s*addc\s*r3, r3, r8
+\s*[0-9a-f]*:\s*0c44\s*cmphs\s*r4, r4
+\s*[0-9a-f]*:\s*0764\s*subc\s*r4, r4, r6
+\s*[0-9a-f]*:\s*0775\s*subc\s*r5, r5, r7
+\s*[0-9a-f]*:\s*1e26\s*or\s*r6, r6, r2
+\s*[0-9a-f]*:\s*1e37\s*or\s*r7, r7, r3
+\s*[0-9a-f]*:\s*1715\s*xor\s*r5, r5, r1
+\s*[0-9a-f]*:\s*1726\s*xor\s*r6, r6, r2
diff --git a/gas/testsuite/gas/csky/all.s b/gas/testsuite/gas/csky/all.s
new file mode 100644
index 0000000..a21bd47
--- /dev/null
+++ b/gas/testsuite/gas/csky/all.s
@@ -0,0 +1,132 @@
+.text
+all:
+ bkpt
+ sync
+ rte
+ rfe
+ rfi
+ stop
+ wait
+ doze
+ idly4
+ trap 3
+ mvc r1
+ mvcv r2
+ ldq r4-r7, (r2)
+ stq r4-r7, (r2)
+ ldm r1-r15, (r0)
+ dect r2
+ decf r2
+ inct r2
+ incf r2
+ jmp r1
+ jsr r1
+ ff1 r11
+ brev r1
+ xtrb3 r2
+ xtrb2 r2
+ xtrb1 r2
+ xtrb0 r2
+ xtrb0 r1, r2
+ xtrb0 r3, r2
+ zextb r2
+ sextb r2
+ zexth r2
+ sexth r2
+ declt r2
+ decne r1
+ decgt r1
+ clrt r1
+ clrf r1
+ abs r3
+ not r12
+ movt r1, r2
+ mult r3, r4
+ sub r7, r8
+ subu r7, r8
+ addc r9, r10
+ subc r11, r12
+ movf r12, r13
+ lsr r12, r13
+ cmphs r13, r14
+ cmplt r13, r14
+ tst r13, r14
+ cmpne r13, r14
+ psrclr ee, ie, fe
+ mov r3, r5
+ bgenr r2, r3
+ and r3, r4
+ ixw r3, r4
+ asr r3, r4
+ addu r3, r4
+ ixh r2, r3
+ andn r3, r4
+ addi r3, 32
+ cmplti r3, 32
+ subi r3, 2
+ rsubi r3, 2
+ cmpnei r3, 3
+ bmaski r3, 8
+ divu r3, r1
+ mflos r2
+ mfhis r2
+ mtlo r2
+ mthi r2
+ mflo r2
+ mfhi r2
+ andi r3, 3
+ bclri r3, 3
+ bgeni r3, 9
+ bgeni r3, 6
+ divs r3, r1
+ divs r3, r2
+ bseti r3, 9
+ btsti r3, 9
+ xsr r3
+ rotli r3, 2
+ asrc r3
+ asri r1, 3
+ movi r7, 127
+ ld r2, (r0, 0)
+ ldw r2, (r0, 4)
+ ld.w r2, (r0, 8)
+ st r2, (r0, 0)
+ stw r2, (r0, 4)
+ st.w r2, (r0, 8)
+ ldh r2, (r0, 2)
+ ld.h r2, (r0, 4)
+ sth r2, (r0, 2)
+ st.h r2, (r0, 4)
+ ldb r2, (r0, 0)
+ ld.b r2, (r0, 1)
+ stb r2, (r0, 0)
+ st.b r2, (r0, 1)
+ bt all
+ bf all
+ br all
+ setc
+ clrc
+ tstle r5
+ cmplei r3, 6
+ neg r7
+ tstne r6
+ tstlt r0
+ mclri r3, 0x80000000
+ mgeni r4, 0x40
+ mgeni r4, 0x80
+ mseti r1, 0x10000
+ mtsti r4, 16
+ rori r6, 20
+ rotri r2, 1
+ nop
+ idly 4
+ rolc r4, 1
+ rotlc r5, 1
+ sxtrb0 r1, r2
+ sxtrb1 r1, r3
+ sxtrb2 r1, r4
+ movtf r1, r2, r3
+ addc64 r2, r2, r7
+ subc64 r4, r4, r6
+ or64 r6, r6, r2
+ xor64 r5, r5, r1
diff --git a/gas/testsuite/gas/csky/bsr1.d b/gas/testsuite/gas/csky/bsr1.d
new file mode 100644
index 0000000..91ba60d
--- /dev/null
+++ b/gas/testsuite/gas/csky/bsr1.d
@@ -0,0 +1,12 @@
+# name: bsr1 - csky
+#as: -mcpu=ck610
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]:\s*ffff\s*bsr\s*0x0\s*\/\/\s*0\s*\<lable\>
+\s*[0-9a-f]:\s*f7fe\s*br\s*0x0\s*\/\/\s*0\s*\<lable*\>
+\s*[0-9a-f]:\s*e7fd\s*bt\s*0x0\s*\/\/\s*0\s*\<lable*\>
+\s*[0-9a-f]:\s*effc\s*bf\s*0x0\s*\/\/\s*0\s*\<lable*\>
diff --git a/gas/testsuite/gas/csky/bsr1.s b/gas/testsuite/gas/csky/bsr1.s
new file mode 100644
index 0000000..8cc5c81
--- /dev/null
+++ b/gas/testsuite/gas/csky/bsr1.s
@@ -0,0 +1,6 @@
+.text
+lable:
+ bsr lable
+ br lable
+ bt lable
+ bf lable
diff --git a/gas/testsuite/gas/csky/bsr2.d b/gas/testsuite/gas/csky/bsr2.d
new file mode 100644
index 0000000..c538acd
--- /dev/null
+++ b/gas/testsuite/gas/csky/bsr2.d
@@ -0,0 +1,9 @@
+# name: bsr2 - csky
+#as: -mcpu=ck610
+#objdump: -r
+
+.*: +file format .*csky.*
+
+RELOCATION RECORDS FOR \[\.text\]:
+#...
+[0-9a-f]*\s*R_CKCORE_PCREL_IMM11BY2\s*hello
diff --git a/gas/testsuite/gas/csky/bsr2.s b/gas/testsuite/gas/csky/bsr2.s
new file mode 100644
index 0000000..0bed607
--- /dev/null
+++ b/gas/testsuite/gas/csky/bsr2.s
@@ -0,0 +1,3 @@
+.text
+lable:
+ bsr hello
diff --git a/gas/testsuite/gas/csky/csky.exp b/gas/testsuite/gas/csky/csky.exp
new file mode 100644
index 0000000..1f18b39
--- /dev/null
+++ b/gas/testsuite/gas/csky/csky.exp
@@ -0,0 +1,7 @@
+#
+# Some CSKY tests
+#
+
+if {[istarget csky*-*-*]} {
+ run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+}
diff --git a/gas/testsuite/gas/csky/csky_vdsp.d b/gas/testsuite/gas/csky/csky_vdsp.d
new file mode 100644
index 0000000..0e2eaa2
--- /dev/null
+++ b/gas/testsuite/gas/csky/csky_vdsp.d
@@ -0,0 +1,364 @@
+# name: csky - vdsp
+#as: -mcpu=ck810v -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*f8623c02\s*vstrq\.8\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623d02\s*vstrq\.16\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623e02\s*vstrq\.32\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623402\s*vldrq\.8\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623502\s*vldrq\.16\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623602\s*vldrq\.32\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623802\s*vstrd\.8\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623902\s*vstrd\.16\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623a02\s*vstrd\.32\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623002\s*vldrd\.8\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623102\s*vldrd\.16\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8623202\s*vldrd\.32\s*fr2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f8022412\s*vldq\.8\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022512\s*vldq\.16\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022612\s*vldq\.32\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022c12\s*vstq\.8\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022d12\s*vstq\.16\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022e12\s*vstq\.32\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022022\s*vldd\.8\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022122\s*vldd\.16\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022222\s*vldd\.32\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022822\s*vstd\.8\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022922\s*vstd\.16\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*f8022a22\s*vstd\.32\s*fr2,\s*\(r2,\s*0x10\)
+\s*[0-9a-f]*:\s*c43eb020\s*vmulsh\s*r30,\s*r1
+\s*[0-9a-f]*:\s*c7e0b040\s*vmulsha\s*r0,\s*r31
+\s*[0-9a-f]*:\s*c58cb420\s*vmulsw\s*r12,\s*r12
+\s*[0-9a-f]*:\s*c6bcb440\s*vmulswa\s*r28,\s*r21
+\s*[0-9a-f]*:\s*c481b480\s*vmulsws\s*r1,\s*r4
+\s*[0-9a-f]*:\s*f9221201\s*vmfvr.u8\s*r1,\s*vr2\[9\]
+\s*[0-9a-f]*:\s*f8041223\s*vmfvr.u16\s*r3,\s*vr4\[0\]
+\s*[0-9a-f]*:\s*f8a8125f\s*vmfvr.u32\s*r31,\s*vr8\[5\]
+\s*[0-9a-f]*:\s*f824128d\s*vmfvr.s8\s*r13,\s*vr4\[1\]
+\s*[0-9a-f]*:\s*f9af12b7\s*vmfvr.s16\s*r23,\s*vr15\[13\]
+\s*[0-9a-f]*:\s*f8101305\s*vmtvr.u8\s*vr5\[0\],\s*r16
+\s*[0-9a-f]*:\s*f8ea1324\s*vmtvr.u16\s*vr4\[7\],\s*r10
+\s*[0-9a-f]*:\s*f9ea134f\s*vmtvr.u32\s*vr15\[15\],\s*r10
+\s*[0-9a-f]*:\s*f94a0e81\s*vdup.8\s*fr1,\s*vr10\[10\]
+\s*[0-9a-f]*:\s*f83a0e8f\s*vdup.16\s*fr15,\s*vr10\[1\]
+\s*[0-9a-f]*:\s*faaa0e87\s*vdup.32\s*fr7,\s*vr10\[5\]
+\s*[0-9a-f]*:\s*f8030c02\s*vmov\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030062\s*vcadd\.eu8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130062\s*vcadd\.eu16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030072\s*vcadd\.es8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130072\s*vcadd\.es16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030c22\s*vmov\.eu8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130c22\s*vmov\.eu16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030c32\s*vmov\.es8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130c32\s*vmov\.es16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130d02\s*vmov\.u16\.l\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030d02\s*vmov\.u32\.l\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130d12\s*vmov\.s16\.l\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030d12\s*vmov\.s32\.l\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130d42\s*vmov\.u16\.sl\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030d42\s*vmov\.u32\.sl\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130d52\s*vmov\.s16\.sl\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030d52\s*vmov\.s32\.sl\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130d62\s*vmov\.u16\.h\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030d62\s*vmov\.u32\.h\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130d72\s*vmov\.s16\.h\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030d72\s*vmov\.s32\.h\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130d82\s*vmov\.u16\.rh\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030d82\s*vmov\.u32\.rh\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130d92\s*vmov\.s16\.rh\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030d92\s*vmov\.s32\.rh\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130dc2\s*vstou\.u16\.sl\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030dc2\s*vstou\.u32\.sl\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130dd2\s*vstou\.s16\.sl\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030dd2\s*vstou\.s32\.sl\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030e62\s*vrev\.8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130e62\s*vrev\.16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030e62\s*vrev\.32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030ea2\s*vcnt1\.8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030ec2\s*vclz\.8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130ec2\s*vclz\.16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030ec2\s*vclz\.32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030ee2\s*vcls\.u8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130ee2\s*vcls\.u16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030ee2\s*vcls\.u32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030ef2\s*vcls\.s8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130ef2\s*vcls\.s16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030ef2\s*vcls\.s32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8031012\s*vabs\.s8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8131012\s*vabs\.s16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa031012\s*vabs\.s32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8031042\s*vabs\.u8\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8131042\s*vabs\.u16\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa031042\s*vabs\.u32\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8031052\s*vabs\.s8\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8131052\s*vabs\.s16\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa031052\s*vabs\.s32\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8031082\s*vneg\.u8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8131082\s*vneg\.u16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa031082\s*vneg\.u32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8031092\s*vneg\.s8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8131092\s*vneg\.s16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa031092\s*vneg\.s32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f80310c2\s*vneg\.u8\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f81310c2\s*vneg\.u16\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa0310c2\s*vneg\.u32\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f80310d2\s*vneg\.s8\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f81310d2\s*vneg\.s16\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa0310d2\s*vneg\.s32\.s\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030882\s*vcmphsz\.u8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130882\s*vcmphsz\.u16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030882\s*vcmphsz\.u32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8030892\s*vcmphsz\.s8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8130892\s*vcmphsz\.s16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa030892\s*vcmphsz\.s32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f80308a2\s*vcmpltz\.u8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f81308a2\s*vcmpltz\.u16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa0308a2\s*vcmpltz\.u32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f80308b2\s*vcmpltz\.s8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f81308b2\s*vcmpltz\.s16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa0308b2\s*vcmpltz\.s32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f80308c2\s*vcmpnez\.u8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f81308c2\s*vcmpnez\.u16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa0308c2\s*vcmpnez\.u32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f80308d2\s*vcmpnez\.s8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f80308d2\s*vcmpnez\.s8\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f81308d2\s*vcmpnez\.s16\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*fa0308d2\s*vcmpnez\.s32\s*vr2,\s*vr3
+\s*[0-9a-f]*:\s*f8830f42\s*vtrch\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930f42\s*vtrch\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830f42\s*vtrch\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830f62\s*vtrcl\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930f62\s*vtrcl\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830f62\s*vtrcl\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830002\s*vadd\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930002\s*vadd\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830002\s*vadd\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830012\s*vadd\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930012\s*vadd\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830012\s*vadd\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830022\s*vadd\.eu8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930022\s*vadd\.eu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830032\s*vadd\.es8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930032\s*vadd\.es16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830042\s*vcadd\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930042\s*vcadd\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830042\s*vcadd\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830052\s*vcadd\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930052\s*vcadd\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830052\s*vcadd\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930142\s*vadd\.xu16\.sl\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830142\s*vadd\.xu32\.sl\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930152\s*vadd\.xs16\.sl\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830152\s*vadd\.xs32\.sl\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930162\s*vadd\.xu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830162\s*vadd\.xu32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930172\s*vadd\.xs16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830172\s*vadd\.xs32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830182\s*vaddh\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930182\s*vaddh\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830182\s*vaddh\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830192\s*vaddh\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930192\s*vaddh\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830192\s*vaddh\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88301a2\s*vaddh\.u8\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89301a2\s*vaddh\.u16\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8301a2\s*vaddh\.u32\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88301b2\s*vaddh\.s8\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89301b2\s*vaddh\.s16\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8301b2\s*vaddh\.s32\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88301c2\s*vadd\.u8\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89301c2\s*vadd\.u16\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8301c2\s*vadd\.u32\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88301d2\s*vadd\.s8\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89301d2\s*vadd\.s16\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8301d2\s*vadd\.s32\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830202\s*vsub\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930202\s*vsub\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830202\s*vsub\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830212\s*vsub\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930212\s*vsub\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830212\s*vsub\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830222\s*vsub\.eu8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930222\s*vsub\.eu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830232\s*vsub\.es8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930232\s*vsub\.es16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830242\s*vsabs\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930242\s*vsabs\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830242\s*vsabs\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830252\s*vsabs\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930252\s*vsabs\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830252\s*vsabs\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830262\s*vsabs\.eu8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930262\s*vsabs\.eu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830272\s*vsabs\.es8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930272\s*vsabs\.es16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830282\s*vsabsa\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930282\s*vsabsa\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830282\s*vsabsa\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830292\s*vsabsa\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930292\s*vsabsa\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830292\s*vsabsa\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88302a2\s*vsabsa\.eu8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89302a2\s*vsabsa\.eu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88302b2\s*vsabsa\.es8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89302b2\s*vsabsa\.es16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930362\s*vsub\.xu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830362\s*vsub\.xu32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930372\s*vsub\.xs16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830372\s*vsub\.xs32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830382\s*vsubh\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930382\s*vsubh\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830382\s*vsubh\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830392\s*vsubh\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930392\s*vsubh\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830392\s*vsubh\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88303a2\s*vsubh\.u8\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89303a2\s*vsubh\.u16\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8303a2\s*vsubh\.u32\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88303b2\s*vsubh\.s8\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89303b2\s*vsubh\.s16\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8303b2\s*vsubh\.s32\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88303c2\s*vsub\.u8\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89303c2\s*vsub\.u16\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8303c2\s*vsub\.u32\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88303d2\s*vsub\.s8\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89303d2\s*vsub\.s16\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8303d2\s*vsub\.s32\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830402\s*vmul\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930402\s*vmul\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830402\s*vmul\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830412\s*vmul\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930412\s*vmul\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830412\s*vmul\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830422\s*vmul\.eu8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930422\s*vmul\.eu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830432\s*vmul\.es8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930432\s*vmul\.es16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830442\s*vmula\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930442\s*vmula\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830442\s*vmula\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830452\s*vmula\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930452\s*vmula\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830452\s*vmula\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830462\s*vmula\.eu8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930462\s*vmula\.eu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830462\s*vmula\.eu32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830472\s*vmula\.es8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930472\s*vmula\.es16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830472\s*vmula\.es32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830482\s*vmuls\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930482\s*vmuls\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830482\s*vmuls\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830492\s*vmuls\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930492\s*vmuls\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830492\s*vmuls\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88304a2\s*vmuls\.eu8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89304a2\s*vmuls\.eu16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88304b2\s*vmuls\.es8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89304b2\s*vmuls\.es16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830682\s*vshr\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930682\s*vshr\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830682\s*vshr\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830692\s*vshr\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930692\s*vshr\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830692\s*vshr\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88306c2\s*vshr\.u8\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89306c2\s*vshr\.u16\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8306c2\s*vshr\.u32\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88306d2\s*vshr\.s8\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89306d2\s*vshr\.s16\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8306d2\s*vshr\.s32\.r\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830782\s*vshl\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930782\s*vshl\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830782\s*vshl\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830792\s*vshl\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930792\s*vshl\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830792\s*vshl\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88307c2\s*vshl\.u8\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89307c2\s*vshl\.u16\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8307c2\s*vshl\.u32\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88307d2\s*vshl\.s8\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89307d2\s*vshl\.s16\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8307d2\s*vshl\.s32\.s\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830802\s*vcmphs\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930802\s*vcmphs\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830802\s*vcmphs\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830812\s*vcmphs\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930812\s*vcmphs\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830812\s*vcmphs\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830822\s*vcmplt\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930822\s*vcmplt\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830822\s*vcmplt\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830832\s*vcmplt\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930832\s*vcmplt\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830832\s*vcmplt\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830842\s*vcmpne\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930842\s*vcmpne\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830842\s*vcmpne\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830852\s*vcmpne\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930852\s*vcmpne\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830852\s*vcmpne\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830902\s*vmax\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930902\s*vmax\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830902\s*vmax\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830912\s*vmax\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930912\s*vmax\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830912\s*vmax\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830922\s*vmin\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930922\s*vmin\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830922\s*vmin\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830932\s*vmin\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930932\s*vmin\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830932\s*vmin\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830982\s*vcmax\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930982\s*vcmax\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830982\s*vcmax\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830992\s*vcmax\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930992\s*vcmax\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830992\s*vcmax\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88309a2\s*vcmin\.u8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89309a2\s*vcmin\.u16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8309a2\s*vcmin\.u32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f88309b2\s*vcmin\.s8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f89309b2\s*vcmin\.s16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa8309b2\s*vcmin\.s32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830a02\s*vand\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930a02\s*vand\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830a02\s*vand\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830a22\s*vandn\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930a22\s*vandn\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830a22\s*vandn\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830a42\s*vor\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930a42\s*vor\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830a42\s*vor\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830a62\s*vnor\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930a62\s*vnor\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830a62\s*vnor\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830a82\s*vxor\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930a82\s*vxor\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830a82\s*vxor\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830b22\s*vtst\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930b22\s*vtst\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830b22\s*vtst\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830f02\s*vbpermz\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930f02\s*vbpermz\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830f02\s*vbpermz\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830f22\s*vbperm\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930f22\s*vbperm\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830f22\s*vbperm\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830fc2\s*vdch\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930fc2\s*vdch\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830fc2\s*vdch\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830fe2\s*vdcl\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930fe2\s*vdcl\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830fe2\s*vdcl\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830f82\s*vich\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930f82\s*vich\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830f82\s*vich\.32\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8830fa2\s*vicl\.8\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*f8930fa2\s*vicl\.16\s*vr2,\s*vr3,\s*vr4
+\s*[0-9a-f]*:\s*fa830fa2\s*vicl\.32\s*vr2,\s*vr3,\s*vr4
diff --git a/gas/testsuite/gas/csky/csky_vdsp.s b/gas/testsuite/gas/csky/csky_vdsp.s
new file mode 100644
index 0000000..7ca46b7
--- /dev/null
+++ b/gas/testsuite/gas/csky/csky_vdsp.s
@@ -0,0 +1,359 @@
+
+.text
+vdsp_instructions:
+ vstrq.8 vr2, (r2, r3 << 0)
+ vstrq.16 vr2, (r2, r3 << 0)
+ vstrq.32 vr2, (r2, r3 << 0)
+ vldrq.8 vr2, (r2, r3 << 0)
+ vldrq.16 vr2, (r2, r3 << 0)
+ vldrq.32 vr2, (r2, r3 << 0)
+ vstrd.8 vr2, (r2, r3 << 0)
+ vstrd.16 vr2, (r2, r3 << 0)
+ vstrd.32 vr2, (r2, r3 << 0)
+ vldrd.8 vr2, (r2, r3 << 0)
+ vldrd.16 vr2, (r2, r3 << 0)
+ vldrd.32 vr2, (r2, r3 << 0)
+ vldq.8 vr2, (r2, 16)
+ vldq.16 vr2, (r2, 16)
+ vldq.32 vr2, (r2, 16)
+ vstq.8 vr2, (r2, 16)
+ vstq.16 vr2, (r2, 16)
+ vstq.32 vr2, (r2, 16)
+ vldd.8 vr2, (r2, 16)
+ vldd.16 vr2, (r2, 16)
+ vldd.32 vr2, (r2, 16)
+ vstd.8 vr2, (r2, 16)
+ vstd.16 vr2, (r2, 16)
+ vstd.32 vr2, (r2, 16)
+ vmulsh r30, r1
+ vmulsha r0, r31
+ vmulsw r12, r12
+ vmulswa r28, r21
+ vmulsws r1, r4
+ vmfvr.u8 r1, vr2[9]
+ vmfvr.u16 r3, fr4[0]
+ vmfvr.u32 r31, vr8[5]
+ vmfvr.s8 r13, fr4[1]
+ vmfvr.s16 r23, vr15[13]
+ vmtvr.u8 vr5[0], r16
+ vmtvr.u16 fr4[7], r10
+ vmtvr.u32 vr15 [ 15 ] , r10
+ vdup.8 vr1, vr10[10]
+ vdup.16 vr15, fr10[1]
+ vdup.32 fr7, fr10[5]
+ vmov vr2, vr3
+ vcadd.eu8 vr2, vr3
+ vcadd.eu16 vr2, vr3
+ vcadd.es8 vr2, vr3
+ vcadd.es16 vr2, vr3
+ vmov.eu8 vr2, vr3
+ vmov.eu16 vr2, vr3
+ vmov.es8 vr2, vr3
+ vmov.es16 vr2, vr3
+ vmov.u16.l vr2, vr3
+ vmov.u32.l vr2, vr3
+ vmov.s16.l vr2, vr3
+ vmov.s32.l vr2, vr3
+ vmov.u16.sl vr2, vr3
+ vmov.u32.sl vr2, vr3
+ vmov.s16.sl vr2, vr3
+ vmov.s32.sl vr2, vr3
+ vmov.u16.h vr2, vr3
+ vmov.u32.h vr2, vr3
+ vmov.s16.h vr2, vr3
+ vmov.s32.h vr2, vr3
+ vmov.u16.rh vr2, vr3
+ vmov.u32.rh vr2, vr3
+ vmov.s16.rh vr2, vr3
+ vmov.s32.rh vr2, vr3
+ vstou.u16.sl vr2, vr3
+ vstou.u32.sl vr2, vr3
+ vstou.s16.sl vr2, vr3
+ vstou.s32.sl vr2, vr3
+ vrev.8 vr2, vr3
+ vrev.16 vr2, vr3
+ vrev.32 vr2, vr3
+ vcnt1.8 vr2, vr3
+ vclz.8 vr2, vr3
+ vclz.16 vr2, vr3
+ vclz.32 vr2, vr3
+ vcls.u8 vr2, vr3
+ vcls.u16 vr2, vr3
+ vcls.u32 vr2, vr3
+ vcls.s8 vr2, vr3
+ vcls.s16 vr2, vr3
+ vcls.s32 vr2, vr3
+ vabs.s8 vr2, vr3
+ vabs.s16 vr2, vr3
+ vabs.s32 vr2, vr3
+ vabs.u8.s vr2, vr3
+ vabs.u16.s vr2, vr3
+ vabs.u32.s vr2, vr3
+ vabs.s8.s vr2, vr3
+ vabs.s16.s vr2, vr3
+ vabs.s32.s vr2, vr3
+ vneg.u8 vr2, vr3
+ vneg.u16 vr2, vr3
+ vneg.u32 vr2, vr3
+ vneg.s8 vr2, vr3
+ vneg.s16 vr2, vr3
+ vneg.s32 vr2, vr3
+ vneg.u8.s vr2, vr3
+ vneg.u16.s vr2, vr3
+ vneg.u32.s vr2, vr3
+ vneg.s8.s vr2, vr3
+ vneg.s16.s vr2, vr3
+ vneg.s32.s vr2, vr3
+ vcmphsz.u8 vr2, vr3
+ vcmphsz.u16 vr2, vr3
+ vcmphsz.u32 vr2, vr3
+ vcmphsz.s8 vr2, vr3
+ vcmphsz.s16 vr2, vr3
+ vcmphsz.s32 vr2, vr3
+ vcmpltz.u8 vr2, vr3
+ vcmpltz.u16 vr2, vr3
+ vcmpltz.u32 vr2, vr3
+ vcmpltz.s8 vr2, vr3
+ vcmpltz.s16 vr2, vr3
+ vcmpltz.s32 vr2, vr3
+ vcmpnez.u8 vr2, vr3
+ vcmpnez.u16 vr2, vr3
+ vcmpnez.u32 vr2, vr3
+ vcmpnez.s8 vr2, vr3
+ vcmpnez.s8 vr2, vr3
+ vcmpnez.s16 vr2, vr3
+ vcmpnez.s32 vr2, vr3
+ vtrch.8 vr2, vr3, vr4
+ vtrch.16 vr2, vr3, vr4
+ vtrch.32 vr2, vr3, vr4
+ vtrcl.8 vr2, vr3, vr4
+ vtrcl.16 vr2, vr3, vr4
+ vtrcl.32 vr2, vr3, vr4
+ vadd.u8 vr2, vr3, vr4
+ vadd.u16 vr2, vr3, vr4
+ vadd.u32 vr2, vr3, vr4
+ vadd.s8 vr2, vr3, vr4
+ vadd.s16 vr2, vr3, vr4
+ vadd.s32 vr2, vr3, vr4
+ vadd.eu8 vr2, vr3, vr4
+ vadd.eu16 vr2, vr3, vr4
+ vadd.es8 vr2, vr3, vr4
+ vadd.es16 vr2, vr3, vr4
+ vcadd.u8 vr2, vr3, vr4
+ vcadd.u16 vr2, vr3, vr4
+ vcadd.u32 vr2, vr3, vr4
+ vcadd.s8 vr2, vr3, vr4
+ vcadd.s16 vr2, vr3, vr4
+ vcadd.s32 vr2, vr3, vr4
+ vadd.xu16.sl vr2, vr3, vr4
+ vadd.xu32.sl vr2, vr3, vr4
+ vadd.xs16.sl vr2, vr3, vr4
+ vadd.xs32.sl vr2, vr3, vr4
+ vadd.xu16 vr2, vr3, vr4
+ vadd.xu32 vr2, vr3, vr4
+ vadd.xs16 vr2, vr3, vr4
+ vadd.xs32 vr2, vr3, vr4
+ vaddh.u8 vr2, vr3, vr4
+ vaddh.u16 vr2, vr3, vr4
+ vaddh.u32 vr2, vr3, vr4
+ vaddh.s8 vr2, vr3, vr4
+ vaddh.s16 vr2, vr3, vr4
+ vaddh.s32 vr2, vr3, vr4
+ vaddh.u8.r vr2, vr3, vr4
+ vaddh.u16.r vr2, vr3, vr4
+ vaddh.u32.r vr2, vr3, vr4
+ vaddh.s8.r vr2, vr3, vr4
+ vaddh.s16.r vr2, vr3, vr4
+ vaddh.s32.r vr2, vr3, vr4
+ vadd.u8.s vr2, vr3, vr4
+ vadd.u16.s vr2, vr3, vr4
+ vadd.u32.s vr2, vr3, vr4
+ vadd.s8.s vr2, vr3, vr4
+ vadd.s16.s vr2, vr3, vr4
+ vadd.s32.s vr2, vr3, vr4
+ vsub.u8 vr2, vr3, vr4
+ vsub.u16 vr2, vr3, vr4
+ vsub.u32 vr2, vr3, vr4
+ vsub.s8 vr2, vr3, vr4
+ vsub.s16 vr2, vr3, vr4
+ vsub.s32 vr2, vr3, vr4
+ vsub.eu8 vr2, vr3, vr4
+ vsub.eu16 vr2, vr3, vr4
+ vsub.es8 vr2, vr3, vr4
+ vsub.es16 vr2, vr3, vr4
+ vsabs.u8 vr2, vr3, vr4
+ vsabs.u16 vr2, vr3, vr4
+ vsabs.u32 vr2, vr3, vr4
+ vsabs.s8 vr2, vr3, vr4
+ vsabs.s16 vr2, vr3, vr4
+ vsabs.s32 vr2, vr3, vr4
+ vsabs.eu8 vr2, vr3, vr4
+ vsabs.eu16 vr2, vr3, vr4
+ vsabs.es8 vr2, vr3, vr4
+ vsabs.es16 vr2, vr3, vr4
+ vsabsa.u8 vr2, vr3, vr4
+ vsabsa.u16 vr2, vr3, vr4
+ vsabsa.u32 vr2, vr3, vr4
+ vsabsa.s8 vr2, vr3, vr4
+ vsabsa.s16 vr2, vr3, vr4
+ vsabsa.s32 vr2, vr3, vr4
+ vsabsa.eu8 vr2, vr3, vr4
+ vsabsa.eu16 vr2, vr3, vr4
+ vsabsa.es8 vr2, vr3, vr4
+ vsabsa.es16 vr2, vr3, vr4
+ vsub.xu16 vr2, vr3, vr4
+ vsub.xu32 vr2, vr3, vr4
+ vsub.xs16 vr2, vr3, vr4
+ vsub.xs32 vr2, vr3, vr4
+ vsubh.u8 vr2, vr3, vr4
+ vsubh.u16 vr2, vr3, vr4
+ vsubh.u32 vr2, vr3, vr4
+ vsubh.s8 vr2, vr3, vr4
+ vsubh.s16 vr2, vr3, vr4
+ vsubh.s32 vr2, vr3, vr4
+ vsubh.u8.r vr2, vr3, vr4
+ vsubh.u16.r vr2, vr3, vr4
+ vsubh.u32.r vr2, vr3, vr4
+ vsubh.s8.r vr2, vr3, vr4
+ vsubh.s16.r vr2, vr3, vr4
+ vsubh.s32.r vr2, vr3, vr4
+ vsub.u8.s vr2, vr3, vr4
+ vsub.u16.s vr2, vr3, vr4
+ vsub.u32.s vr2, vr3, vr4
+ vsub.s8.s vr2, vr3, vr4
+ vsub.s16.s vr2, vr3, vr4
+ vsub.s32.s vr2, vr3, vr4
+ vmul.u8 vr2, vr3, vr4
+ vmul.u16 vr2, vr3, vr4
+ vmul.u32 vr2, vr3, vr4
+ vmul.s8 vr2, vr3, vr4
+ vmul.s16 vr2, vr3, vr4
+ vmul.s32 vr2, vr3, vr4
+ vmul.eu8 vr2, vr3, vr4
+ vmul.eu16 vr2, vr3, vr4
+ vmul.es8 vr2, vr3, vr4
+ vmul.es16 vr2, vr3, vr4
+ vmula.u8 vr2, vr3, vr4
+ vmula.u16 vr2, vr3, vr4
+ vmula.u32 vr2, vr3, vr4
+ vmula.s8 vr2, vr3, vr4
+ vmula.s16 vr2, vr3, vr4
+ vmula.s32 vr2, vr3, vr4
+ vmula.eu8 vr2, vr3, vr4
+ vmula.eu16 vr2, vr3, vr4
+ vmula.eu32 vr2, vr3, vr4
+ vmula.es8 vr2, vr3, vr4
+ vmula.es16 vr2, vr3, vr4
+ vmula.es32 vr2, vr3, vr4
+ vmuls.u8 vr2, vr3, vr4
+ vmuls.u16 vr2, vr3, vr4
+ vmuls.u32 vr2, vr3, vr4
+ vmuls.s8 vr2, vr3, vr4
+ vmuls.s16 vr2, vr3, vr4
+ vmuls.s32 vr2, vr3, vr4
+ vmuls.eu8 vr2, vr3, vr4
+ vmuls.eu16 vr2, vr3, vr4
+ vmuls.es8 vr2, vr3, vr4
+ vmuls.es16 vr2, vr3, vr4
+ vshr.u8 vr2, vr3, vr4
+ vshr.u16 vr2, vr3, vr4
+ vshr.u32 vr2, vr3, vr4
+ vshr.s8 vr2, vr3, vr4
+ vshr.s16 vr2, vr3, vr4
+ vshr.s32 vr2, vr3, vr4
+ vshr.u8.r vr2, vr3, vr4
+ vshr.u16.r vr2, vr3, vr4
+ vshr.u32.r vr2, vr3, vr4
+ vshr.s8.r vr2, vr3, vr4
+ vshr.s16.r vr2, vr3, vr4
+ vshr.s32.r vr2, vr3, vr4
+ vshl.u8 vr2, vr3, vr4
+ vshl.u16 vr2, vr3, vr4
+ vshl.u32 vr2, vr3, vr4
+ vshl.s8 vr2, vr3, vr4
+ vshl.s16 vr2, vr3, vr4
+ vshl.s32 vr2, vr3, vr4
+ vshl.u8.s vr2, vr3, vr4
+ vshl.u16.s vr2, vr3, vr4
+ vshl.u32.s vr2, vr3, vr4
+ vshl.s8.s vr2, vr3, vr4
+ vshl.s16.s vr2, vr3, vr4
+ vshl.s32.s vr2, vr3, vr4
+ vcmphs.u8 vr2, vr3, vr4
+ vcmphs.u16 vr2, vr3, vr4
+ vcmphs.u32 vr2, vr3, vr4
+ vcmphs.s8 vr2, vr3, vr4
+ vcmphs.s16 vr2, vr3, vr4
+ vcmphs.s32 vr2, vr3, vr4
+ vcmplt.u8 vr2, vr3, vr4
+ vcmplt.u16 vr2, vr3, vr4
+ vcmplt.u32 vr2, vr3, vr4
+ vcmplt.s8 vr2, vr3, vr4
+ vcmplt.s16 vr2, vr3, vr4
+ vcmplt.s32 vr2, vr3, vr4
+ vcmpne.u8 vr2, vr3, vr4
+ vcmpne.u16 vr2, vr3, vr4
+ vcmpne.u32 vr2, vr3, vr4
+ vcmpne.s8 vr2, vr3, vr4
+ vcmpne.s16 vr2, vr3, vr4
+ vcmpne.s32 vr2, vr3, vr4
+ vmax.u8 vr2, vr3, vr4
+ vmax.u16 vr2, vr3, vr4
+ vmax.u32 vr2, vr3, vr4
+ vmax.s8 vr2, vr3, vr4
+ vmax.s16 vr2, vr3, vr4
+ vmax.s32 vr2, vr3, vr4
+ vmin.u8 vr2, vr3, vr4
+ vmin.u16 vr2, vr3, vr4
+ vmin.u32 vr2, vr3, vr4
+ vmin.s8 vr2, vr3, vr4
+ vmin.s16 vr2, vr3, vr4
+ vmin.s32 vr2, vr3, vr4
+ vcmax.u8 vr2, vr3, vr4
+ vcmax.u16 vr2, vr3, vr4
+ vcmax.u32 vr2, vr3, vr4
+ vcmax.s8 vr2, vr3, vr4
+ vcmax.s16 vr2, vr3, vr4
+ vcmax.s32 vr2, vr3, vr4
+ vcmin.u8 vr2, vr3, vr4
+ vcmin.u16 vr2, vr3, vr4
+ vcmin.u32 vr2, vr3, vr4
+ vcmin.s8 vr2, vr3, vr4
+ vcmin.s16 vr2, vr3, vr4
+ vcmin.s32 vr2, vr3, vr4
+ vand.8 vr2, vr3, vr4
+ vand.16 vr2, vr3, vr4
+ vand.32 vr2, vr3, vr4
+ vandn.8 vr2, vr3, vr4
+ vandn.16 vr2, vr3, vr4
+ vandn.32 vr2, vr3, vr4
+ vor.8 vr2, vr3, vr4
+ vor.16 vr2, vr3, vr4
+ vor.32 vr2, vr3, vr4
+ vnor.8 vr2, vr3, vr4
+ vnor.16 vr2, vr3, vr4
+ vnor.32 vr2, vr3, vr4
+ vxor.8 vr2, vr3, vr4
+ vxor.16 vr2, vr3, vr4
+ vxor.32 vr2, vr3, vr4
+ vtst.8 vr2, vr3, vr4
+ vtst.16 vr2, vr3, vr4
+ vtst.32 vr2, vr3, vr4
+ vbpermz.8 vr2, vr3, vr4
+ vbpermz.16 vr2, vr3, vr4
+ vbpermz.32 vr2, vr3, vr4
+ vbperm.8 vr2, vr3, vr4
+ vbperm.16 vr2, vr3, vr4
+ vbperm.32 vr2, vr3, vr4
+ vdch.8 vr2, vr3, vr4
+ vdch.16 vr2, vr3, vr4
+ vdch.32 vr2, vr3, vr4
+ vdcl.8 vr2, vr3, vr4
+ vdcl.16 vr2, vr3, vr4
+ vdcl.32 vr2, vr3, vr4
+ vich.8 vr2, vr3, vr4
+ vich.16 vr2, vr3, vr4
+ vich.32 vr2, vr3, vr4
+ vicl.8 vr2, vr3, vr4
+ vicl.16 vr2, vr3, vr4
+ vicl.32 vr2, vr3, vr4
diff --git a/gas/testsuite/gas/csky/cskyv2_all.d b/gas/testsuite/gas/csky/cskyv2_all.d
new file mode 100644
index 0000000..b17a5e7
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_all.d
@@ -0,0 +1,325 @@
+# name: csky - all
+#as: -mcpu=ck810 -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*0000\s*bkpt
+\s*[0-9a-f]*:\s*3316\s*movi\s*r3,\s*22
+\s*[0-9a-f]*:\s*ea100016\s*movi\s*r16,\s*22
+\s*[0-9a-f]*:\s*ea03012c\s*movi\s*r3,\s*300
+\s*[0-9a-f]*:\s*c4104834\s*lsli\s*r20,\s*r16,\s*0
+\s*[0-9a-f]*:\s*c6824848\s*lsri\s*r8,\s*r2,\s*20
+\s*[0-9a-f]*:\s*5227\s*asri\s*r1,\s*r2,\s*7
+\s*[0-9a-f]*:\s*6049\s*addc\s*r1,\s*r2
+\s*[0-9a-f]*:\s*c4310051\s*addc\s*r17,\s*r17,\s*r1
+\s*[0-9a-f]*:\s*c4620041\s*addc\s*r1,\s*r2,\s*r3
+\s*[0-9a-f]*:\s*6049\s*addc\s*r1,\s*r2
+\s*[0-9a-f]*:\s*c6210041\s*addc\s*r1,\s*r1,\s*r17
+\s*[0-9a-f]*:\s*c7d20052\s*addc\s*r18,\s*r18,\s*r30
+\s*[0-9a-f]*:\s*604b\s*subc\s*r1,\s*r2
+\s*[0-9a-f]*:\s*c4310111\s*subc\s*r17,\s*r17,\s*r1
+\s*[0-9a-f]*:\s*c4620101\s*subc\s*r1,\s*r2,\s*r3
+\s*[0-9a-f]*:\s*c4220101\s*subc\s*r1,\s*r2,\s*r1
+\s*[0-9a-f]*:\s*c6210101\s*subc\s*r1,\s*r1,\s*r17
+\s*[0-9a-f]*:\s*c7d20112\s*subc\s*r18,\s*r18,\s*r30
+\s*[0-9a-f]*:\s*650c\s*cmphs\s*r3,\s*r4
+\s*[0-9a-f]*:\s*650d\s*cmplt\s*r3,\s*r4
+\s*[0-9a-f]*:\s*650e\s*cmpne\s*r3,\s*r4
+\s*[0-9a-f]*:\s*64c3\s*mvcv\s*r3
+\s*[0-9a-f]*:\s*c4000610\s*mvcv\s*r16
+\s*[0-9a-f]*:\s*6848\s*and\s*r1,\s*r2
+\s*[0-9a-f]*:\s*6849\s*andn\s*r1,\s*r2
+\s*[0-9a-f]*:\s*690e\s*tst\s*r3,\s*r4
+\s*[0-9a-f]*:\s*c4902080\s*tst\s*r16,\s*r4
+\s*[0-9a-f]*:\s*680f\s*tstnbz\s*r3
+\s*[0-9a-f]*:\s*c4102100\s*tstnbz\s*r16
+\s*[0-9a-f]*:\s*c6f22432\s*or\s*r18,\s*r18,\s*r23
+\s*[0-9a-f]*:\s*6c49\s*xor\s*r1,\s*r2
+\s*[0-9a-f]*:\s*6c4a\s*nor\s*r1,\s*r2
+\s*[0-9a-f]*:\s*6c8f\s*mov\s*r2,\s*r3
+\s*[0-9a-f]*:\s*7808\s*jmp\s*r2
+\s*[0-9a-f]*:\s*e8d00000\s*jmp\s*r16
+\s*[0-9a-f]*:\s*7bc9\s*jsr\s*r2
+\s*[0-9a-f]*:\s*e8f00000\s*jsr\s*r16
+\s*[0-9a-f]*:\s*783c\s*rts
+\s*[0-9a-f]*:\s*e8cf0000\s*rts
+\s*[0-9a-f]*:\s*6c03\s*mov\s*r0, \s*r0
+\s*[0-9a-f]*:\s*c4364036\s*lsl\s*r22,\s*r22,\s*r1
+\s*[0-9a-f]*:\s*c4224041\s*lsr\s*r1,\s*r2,\s*r1
+\s*[0-9a-f]*:\s*704a\s*asr\s*r1,\s*r2
+\s*[0-9a-f]*:\s*c6014101\s*rotl\s*r1,\s*r1,\s*r16
+\s*[0-9a-f]*:\s*748c\s*zextb\s*r2,\s*r3
+\s*[0-9a-f]*:\s*748d\s*zexth\s*r2,\s*r3
+\s*[0-9a-f]*:\s*748e\s*sextb\s*r2,\s*r3
+\s*[0-9a-f]*:\s*748f\s*sexth\s*r2,\s*r3
+\s*[0-9a-f]*:\s*788e\s*revb\s*r2,\s*r3
+\s*[0-9a-f]*:\s*788f\s*revh\s*r2,\s*r3
+\s*[0-9a-f]*:\s*c4036090\s*revb\s*r16,\s*r3
+\s*[0-9a-f]*:\s*c4106102\s*revh\s*r2,\s*r16
+\s*[0-9a-f]*:\s*c6218421\s*mult\s*r1,\s*r1,\s*r17
+\s*[0-9a-f]*:\s*7d1c\s*mult\s*r4,\s*r7
+\s*[0-9a-f]*:\s*c6479027\s*mulsh\s*r7,\s*r7,\s*r18
+\s*[0-9a-f]*:\s*7ca1\s*mulsh\s*r2,\s*r8
+\s*[0-9a-f]*:\s*c43e943e\s*mulsw\s*r30,\s*r30,\s*r1
+\s*[0-9a-f]*:\s*c4419421\s*mulsw\s*r1,\s*r1,\s*r2
+\s*[0-9a-f]*:\s*8344\s*ld.b\s*r2,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*8b42\s*ld.h\s*r2,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*9841\s*ld.w\s*r2,\s*\(sp,\s*0x4\)
+\s*[0-9a-f]*:\s*a344\s*st.b\s*r2,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*ab42\s*st.h\s*r2,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*b841\s*st.w\s*r2,\s*\(sp,\s*0x4\)
+\s*[0-9a-f]*:\s*d9030004\s*ld.b\s*r8,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*d8481002\s*ld.h\s*r2,\s*\(r8,\s*0x4\)
+\s*[0-9a-f]*:\s*9841\s*ld.w\s*r2,\s*\(sp,\s*0x4\)
+\s*[0-9a-f]*:\s*dc480004\s*st.b\s*r2,\s*\(r8,\s*0x4\)
+\s*[0-9a-f]*:\s*dc481002\s*st.h\s*r2,\s*\(r8,\s*0x4\)
+\s*[0-9a-f]*:\s*dd0e2001\s*st.w\s*r8,\s*\(sp,\s*0x4\)
+\s*[0-9a-f]*:\s*d8434003\s*ld.bs\s*r2,\s*\(r3,\s*0x3\)
+\s*[0-9a-f]*:\s*d8433001\s*ld.d\s*r2,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*dc433001\s*st.d\s*r2,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*dc437001\s*stex.w\s*r2,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*d8437001\s*ldex.w\s*r2,\s*\(r3,\s*0x4\)
+\s*[0-9a-f]*:\s*140c\s*addi\s*sp,\s*sp,\s*48
+\s*[0-9a-f]*:\s*1b01\s*addi\s*r3,\s*sp,\s*4
+\s*[0-9a-f]*:\s*2113\s*addi\s*r1,\s*20
+\s*[0-9a-f]*:\s*2113\s*addi\s*r1,\s*20
+\s*[0-9a-f]*:\s*e6b50013\s*addi\s*r21,\s*r21,\s*20
+\s*[0-9a-f]*:\s*e42101ff\s*addi\s*r1,\s*r1,\s*512
+\s*[0-9a-f]*:\s*5c42\s*addi\s*r2,\s*r4,\s*1
+\s*[0-9a-f]*:\s*e5040000\s*addi\s*r8,\s*r4,\s*1
+\s*[0-9a-f]*:\s*e4240008\s*addi\s*r1,\s*r4,\s*9
+\s*[0-9a-f]*:\s*cc3c0008\s*addi\s*r1,\s*r28,\s*9
+\s*[0-9a-f]*:\s*e46e0000\s*addi\s*r3,\s*sp,\s*1
+\s*[0-9a-f]*:\s*e46e03ff\s*addi\s*r3,\s*sp,\s*1024
+\s*[0-9a-f]*:\s*e5ce0032\s*addi\s*sp,\s*sp,\s*51
+\s*[0-9a-f]*:\s*e5ce01ff\s*addi\s*sp,\s*sp,\s*512
+\s*[0-9a-f]*:\s*2113\s*addi\s*r1,\s*20
+\s*[0-9a-f]*:\s*5c42\s*addi\s*r2,\s*r4,\s*1
+\s*[0-9a-f]*:\s*e4440000\s*addi\s*r2,\s*r4,\s*1
+\s*[0-9a-f]*:\s*e46e03ff\s*addi\s*r3,\s*sp,\s*1024
+\s*[0-9a-f]*:\s*e5ce0032\s*addi\s*sp,\s*sp,\s*51
+\s*[0-9a-f]*:\s*142c\s*subi\s*sp,\s*sp,\s*48
+\s*[0-9a-f]*:\s*2913\s*subi\s*r1,\s*20
+\s*[0-9a-f]*:\s*2913\s*subi\s*r1,\s*20
+\s*[0-9a-f]*:\s*e6b51013\s*subi\s*r21,\s*r21,\s*20
+\s*[0-9a-f]*:\s*e42111ff\s*subi\s*r1,\s*r1,\s*512
+\s*[0-9a-f]*:\s*5c43\s*subi\s*r2,\s*r4,\s*1
+\s*[0-9a-f]*:\s*e5041000\s*subi\s*r8,\s*r4,\s*1
+\s*[0-9a-f]*:\s*e4241008\s*subi\s*r1,\s*r4,\s*9
+\s*[0-9a-f]*:\s*e43c1008\s*subi\s*r1,\s*r28,\s*9
+\s*[0-9a-f]*:\s*e5ce1032\s*subi\s*sp,\s*sp,\s*51
+\s*[0-9a-f]*:\s*e5ce11ff\s*subi\s*sp,\s*sp,\s*512
+\s*[0-9a-f]*:\s*2913\s*subi\s*r1,\s*20
+\s*[0-9a-f]*:\s*5c43\s*subi\s*r2,\s*r4,\s*1
+\s*[0-9a-f]*:\s*e4441000\s*subi\s*r2,\s*r4,\s*1
+\s*[0-9a-f]*:\s*e5ce1032\s*subi\s*sp,\s*sp,\s*51
+\s*[0-9a-f]*:\s*60c2\s*subu\s*r3,\s*r0
+\s*[0-9a-f]*:\s*6202\s*subu\s*r8,\s*r0
+\s*[0-9a-f]*:\s*c4030089\s*subu\s*r9,\s*r3,\s*r0
+\s*[0-9a-f]*:\s*60c2\s*subu\s*r3,\s*r0
+\s*[0-9a-f]*:\s*6242\s*subu\s*r9,\s*r0
+\s*[0-9a-f]*:\s*c417008d\s*subu\s*r13,\s*r23,\s*r0
+\s*[0-9a-f]*:\s*60c0\s*addu\s*r3,\s*r0
+\s*[0-9a-f]*:\s*6200\s*addu\s*r8,\s*r0
+\s*[0-9a-f]*:\s*c4030029\s*addu\s*r9,\s*r3,\s*r0
+\s*[0-9a-f]*:\s*60c0\s*addu\s*r3,\s*r0
+\s*[0-9a-f]*:\s*6240\s*addu\s*r9,\s*r0
+\s*[0-9a-f]*:\s*c417002d\s*addu\s*r13,\s*r23,\s*r0
+\s*[0-9a-f]*:\s*3921\s*cmplti\s*r1,\s*2
+\s*[0-9a-f]*:\s*eb320003\s*cmplti\s*r18,\s*4
+\s*[0-9a-f]*:\s*670c\s*cmphs\s*r3,\s*r12
+\s*[0-9a-f]*:\s*c6c30420\s*cmphs\s*r3,\s*r22
+\s*[0-9a-f]*:\s*6489\s*cmplt\s*r2,\s*r2
+\s*[0-9a-f]*:\s*c7220440\s*cmplt\s*r2,\s*r25
+\s*[0-9a-f]*:\s*3d20\s*cmplti\s*r5,\s*1
+\s*[0-9a-f]*:\s*eb390000\s*cmplti\s*r25,\s*1
+\s*[0-9a-f]*:\s*3a40\s*cmpnei\s*r2,\s*0
+\s*[0-9a-f]*:\s*eb580000\s*cmpnei\s*r24,\s*0
+\s*[0-9a-f]*:\s*c7e42880\s*btsti\s*r4,\s*31
+\s*[0-9a-f]*:\s*c7f82880\s*btsti\s*r24,\s*31
+\s*[0-9a-f]*:\s*6400\s*cmphs\s*r0,\s*r0
+\s*[0-9a-f]*:\s*6402\s*cmpne\s*r0,\s*r0
+\s*[0-9a-f]*:\s*6089\s*addc\s*r2,\s*r2
+\s*[0-9a-f]*:\s*c6100050\s*addc\s*r16,\s*r16,\s*r16
+\s*[0-9a-f]*:\s*c0a01820\s*sce\s*5
+\s*[0-9a-f]*:\s*c0002820\s*trap\s*2
+\s*[0-9a-f]*:\s*c4402c20\s*clrf\s*r2
+\s*[0-9a-f]*:\s*c7402c40\s*clrt\s*r26
+\s*[0-9a-f]*:\s*c0004020\s*rte
+\s*[0-9a-f]*:\s*c0004420\s*rfi
+\s*[0-9a-f]*:\s*c0004820\s*stop
+\s*[0-9a-f]*:\s*c0004c20\s*wait
+\s*[0-9a-f]*:\s*c0005020\s*doze
+\s*[0-9a-f]*:\s*c0005420\s*we
+\s*[0-9a-f]*:\s*c0005820\s*se
+\s*[0-9a-f]*:\s*c4000517\s*mvc\s*r23
+\s*[0-9a-f]*:\s*c4009823\s*mfhis\s*r3
+\s*[0-9a-f]*:\s*c4009891\s*mflos\s*r17
+\s*[0-9a-f]*:\s*c4009a00\s*mvtc
+\s*[0-9a-f]*:\s*c4009c32\s*mfhi\s*r18
+\s*[0-9a-f]*:\s*c4139c40\s*mthi\s*r19
+\s*[0-9a-f]*:\s*c4009c83\s*mflo\s*r3
+\s*[0-9a-f]*:\s*c4089d00\s*mtlo\s*r8
+\s*[0-9a-f]*:\s*c0000420\s*sync\s*0
+\s*[0-9a-f]*:\s*c0200420\s*sync\s*1
+\s*[0-9a-f]*:\s*c2800420\s*sync\s*20
+\s*[0-9a-f]*:\s*c0601c20\s*idly\s*4
+\s*[0-9a-f]*:\s*c0601c20\s*idly\s*4
+\s*[0-9a-f]*:\s*c0601c20\s*idly\s*4
+\s*[0-9a-f]*:\s*c0801c20\s*idly\s*5
+\s*[0-9a-f]*:\s*c3e01c20\s*idly\s*32
+\s*[0-9a-f]*:\s*fc2044d2\s*cprc\s*\<1,\s*1234\>
+\s*[0-9a-f]*:\s*fc2084d2\s*cpop\s*\<1,\s*1234\>
+\s*[0-9a-f]*:\s*fc3414d2\s*cpwgr\s*r20,\s*\<1,\s*1234\>
+\s*[0-9a-f]*:\s*fc3434d2\s*cpwcr\s*r20,\s*\<1,\s*1234\>
+\s*[0-9a-f]*:\s*fc3404d2\s*cprgr\s*r20,\s*\<1,\s*1234\>
+\s*[0-9a-f]*:\s*fc3424d2\s*cprcr\s*r20,\s*\<1,\s*1234\>
+\s*[0-9a-f]*:\s*320c\s*movi\s*r2,\s*12
+\s*[0-9a-f]*:\s*ea220010\s*movih\s*r2,\s*16
+\s*[0-9a-f]*:\s*ea021000\s*movi\s*r2,\s*4096
+\s*[0-9a-f]*:\s*ea220001\s*movih\s*r2,\s*1
+\s*[0-9a-f]*:\s*1491\s*pop\s*r4, r15
+\s*[0-9a-f]*:\s*1498\s*pop\s*r4-r11, r15
+\s*[0-9a-f]*:\s*ebc00100\s*pop\s*r28
+\s*[0-9a-f]*:\s*ebc00020\s*pop\s*r16
+\s*[0-9a-f]*:\s*14d1\s*push\s*r4, r15
+\s*[0-9a-f]*:\s*14d8\s*push\s*r4-r11, r15
+\s*[0-9a-f]*:\s*ebe00100\s*push\s*r28
+\s*[0-9a-f]*:\s*ebe00020\s*push\s*r16
+\s*[0-9a-f]*:\s*c4625c42\s*ins\s*r3,\s*r2,\s*4,\s*2
+\s*[0-9a-f]*:\s*c4425483\s*zext\s*r3,\s*r2,\s*4,\s*2
+\s*[0-9a-f]*:\s*c4425883\s*sext\s*r3,\s*r2,\s*4,\s*2
+\s*[0-9a-f]*:\s*e4622002\s*andi\s*r3,\s*r2,\s*2
+\s*[0-9a-f]*:\s*e4623002\s*andni\s*r3,\s*r2,\s* 2
+\s*[0-9a-f]*:\s*e462400c\s*xori\s*r3,\s*r2,\s* 12
+\s*[0-9a-f]*:\s*d0621c22\s*ldm\s*r3-r5,\s*\(r2\)
+\s*[0-9a-f]*:\s*d4621c22\s*stm\s*r3-r5,\s*\(r2\)
+\s*[0-9a-f]*:\s*c4410083\s*subu\s*r3,\s*r1,\s*r2
+\s*[0-9a-f]*:\s*d4220023\s*str\.b\s*r3,\s*\(r2,\s*r1\s*<<\s*0\)
+\s*[0-9a-f]*:\s*d4220423\s*str\.h\s*r3,\s*\(r2,\s*r1\s*<<\s*0\)
+\s*[0-9a-f]*:\s*d4220823\s*str\.w\s*r3,\s*\(r2,\s*r1\s*<<\s*0\)
+\s*[0-9a-f]*:\s*d0220043\s*ldr\.b\s*r3,\s*\(r2,\s*r1\s*<<\s*1\)
+\s*[0-9a-f]*:\s*d0220443\s*ldr\.h\s*r3,\s*\(r2,\s*r1\s*<<\s*1\)
+\s*[0-9a-f]*:\s*d0220843\s*ldr\.w\s*r3,\s*\(r2,\s*r1\s*<<\s*1\)
+\s*[0-9a-f]*:\s*d0621022\s*ldr\.bs\s*r2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*d0621042\s*ldr\.bs\s*r2,\s*\(r2,\s*r3\s*<<\s*1\)
+\s*[0-9a-f]*:\s*d0621082\s*ldr\.bs\s*r2,\s*\(r2,\s*r3\s*<<\s*2\)
+\s*[0-9a-f]*:\s*d0621102\s*ldr\.bs\s*r2,\s*\(r2,\s*r3\s*<<\s*3\)
+\s*[0-9a-f]*:\s*d0621422\s*ldr\.hs\s*r2,\s*\(r2,\s*r3\s*<<\s*0\)
+\s*[0-9a-f]*:\s*d0621442\s*ldr\.hs\s*r2,\s*\(r2,\s*r3\s*<<\s*1\)
+\s*[0-9a-f]*:\s*d0621482\s*ldr\.hs\s*r2,\s*\(r2,\s*r3\s*<<\s*2\)
+\s*[0-9a-f]*:\s*d0621502\s*ldr\.hs\s*r2,\s*\(r2,\s*r3\s*<<\s*3\)
+\s*[0-9a-f]*:\s*c4424d03\s*xsr\s*r3,\s*r2,\s*3
+\s*[0-9a-f]*:\s*c4424c83\s*asrc\s*r3,\s*r2,\s*3
+\s*[0-9a-f]*:\s*c4424c43\s*lsrc\s*r3,\s*r2,\s*3
+\s*[0-9a-f]*:\s*c4424c23\s*lslc\s*r3,\s*r2,\s*3
+\s*[0-9a-f]*:\s*c4824903\s*rotli\s*r3,\s*r2,\s*4
+\s*[0-9a-f]*:\s*c4014901\s*rotli\s*r1,\s*r1,\s*0
+\s*[0-9a-f]*:\s*c7e14901\s*rotli\s*r1,\s*r1,\s*31
+\s*[0-9a-f]*:\s*c7304901\s*rotli\s*r1,\s*r16,\s*25
+\s*[0-9a-f]*:\s*c7e14901\s*rotli\s*r1,\s*r1,\s*31
+\s*[0-9a-f]*:\s*c4014901\s*rotli\s*r1,\s*r1,\s*0
+\s*[0-9a-f]*:\s*c4f04901\s*rotli\s*r1,\s*r16,\s*7
+\s*[0-9a-f]*:\s*c4821083\s*decne\s*r3,\s*r2,\s*4
+\s*[0-9a-f]*:\s*c4821043\s*declt\s*r3,\s*r2,\s*4
+\s*[0-9a-f]*:\s*c4821023\s*decgt\s*r3,\s*r2,\s*4
+\s*[0-9a-f]*:\s*c4620d04\s*dect\s*r3,\s*r2,\s*4
+\s*[0-9a-f]*:\s*c4620c84\s*decf\s*r3,\s*r2,\s*4
+\s*[0-9a-f]*:\s*c4620c24\s*incf\s*r3,\s*r2,\s*4
+\s*[0-9a-f]*:\s*c4620c44\s*inct\s*r3,\s*r2,\s*4
+\s*[0-9a-f]*:\s*d0831c23\s*ldm\s*r4-r7,\s*\(r3\)
+\s*[0-9a-f]*:\s*d4831c23\s*stm\s*r4-r7,\s*\(r3\)
+\s*[0-9a-f]*:\s*c1007020\s*psrclr\s*ee
+\s*[0-9a-f]*:\s*c0607020\s*psrclr\s*fe,\s*af
+\s*[0-9a-f]*:\s*c1607420\s*psrset\s*ee,\s*fe,\s*af
+\s*[0-9a-f]*:\s*c1e07420\s*psrset\s*ee,\s*ie,\s*fe,\s*af
+\s*[0-9a-f]*:\s*c4140211\s*abs\s*r17,\s*r20
+\s*[0-9a-f]*:\s*c4155043\s*bgenr\s*r3,\s*r21
+\s*[0-9a-f]*:\s*c4016217\s*brev\s*r23,\s*r1
+\s*[0-9a-f]*:\s*c4037025\s*xtrb0\s*r5,\s*r3
+\s*[0-9a-f]*:\s*c4097043\s*xtrb1\s*r3,\s*r9
+\s*[0-9a-f]*:\s*c4147090\s*xtrb2\s*r16,\s*r20
+\s*[0-9a-f]*:\s*c418710b\s*xtrb3\s*r11,\s*r24
+\s*[0-9a-f]*:\s*c4157c22\s*ff0\s*r2,\s*r21
+\s*[0-9a-f]*:\s*c4017c52\s*ff1\s*r18,\s*r1
+\s*[0-9a-f]*:\s*c0026423\s*mtcr\s*r2,\s*cr<3,\s*0>
+\s*[0-9a-f]*:\s*c0026424\s*mtcr\s*r2,\s*cr<4,\s*0>
+\s*[0-9a-f]*:\s*c0026421\s*mtcr\s*r2,\s*cr<1,\s*0>
+\s*[0-9a-f]*:\s*c0006022\s*mfcr\s*r2,\s*cr<0,\s*0>
+\s*[0-9a-f]*:\s*c0006022\s*mfcr\s*r2,\s*cr<0,\s*0>
+\s*[0-9a-f]*:\s*c0006022\s*mfcr\s*r2,\s*cr<0,\s*0>
+\s*[0-9a-f]*:\s*6c8a\s*nor\s*r2,\s*r2
+\s*[0-9a-f]*:\s*c6102490\s*nor\s*r16,\s*r16,\s*r16
+\s*[0-9a-f]*:\s*c6102482\s*nor\s*r2,\s*r16,\s*r16
+\s*[0-9a-f]*:\s*6c8a\s*nor\s*r2,\s*r2
+\s*[0-9a-f]*:\s*c4830822\s*ixh\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*c4830842\s*ixw\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*c4830882\s*ixd\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*c4838042\s*divs\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*c4838022\s*divu\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*c4220c20\s*incf\s*r1,\s*r2,\s*0
+\s*[0-9a-f]*:\s*c6e20c40\s*inct\s*r23,\s*r2,\s*0
+\s*[0-9a-f]*:\s*ea0800ff\s*movi\s*r8,\s*255
+\s*[0-9a-f]*:\s*c7e05021\s*bmaski\s*r1,\s*32
+\s*[0-9a-f]*:\s*310f\s*movi\s*r1,\s*15
+\s*[0-9a-f]*:\s*c6005021\s*bmaski\s*r1,\s*17
+\s*[0-9a-f]*:\s*ea15ffff\s*movi\s*r21,\s*65535
+\s*[0-9a-f]*:\s*ea0dffff\s*movi\s*r13,\s*65535
+\s*[0-9a-f]*:\s*c7c05021\s*bmaski\s*r1,\s*31
+\s*[0-9a-f]*:\s*c7e05021\s*bmaski\s*r1,\s*32
+\s*[0-9a-f]*:\s*d8026002\s*pldr\s*\(r2,\s*0x8\)
+\s*[0-9a-f]*:\s*dc026002\s*pldw\s*\(r2,\s*0x8\)
+\s*[0-9a-f]*:\s*6c46\s*nor\s*r1,\s*r1
+\s*[0-9a-f]*:\s*2100\s*addi\s*r1,\s*1
+\s*[0-9a-f]*:\s*6c8a\s*nor\s*r2,\s*r2
+\s*[0-9a-f]*:\s*2217\s*addi\s*r2,\s*24
+\s*[0-9a-f]*:\s*c4034c83\s*asrc\s*r3,\s*r3,\s*1
+\s*[0-9a-f]*:\s*c4840c21\s*incf\s*r4,\s*r4,\s*1
+\s*[0-9a-f]*:\s*c5ad0c41\s*inct\s*r13,\s*r13,\s*1
+\s*[0-9a-f]*:\s*c6100c81\s*decf\s*r16,\s*r16,\s*1
+\s*[0-9a-f]*:\s*c4311031\s*decgt\s*r17,\s*r17,\s*1
+\s*[0-9a-f]*:\s*c4331053\s*declt\s*r19,\s*r19,\s*1
+\s*[0-9a-f]*:\s*c4341094\s*decne\s*r20,\s*r20,\s*1
+\s*[0-9a-f]*:\s*c7ff0d01\s*dect\s*r31,\s*r31,\s*1
+\s*[0-9a-f]*:\s*c40b4c2b\s*lslc\s*r11,\s*r11,\s*1
+\s*[0-9a-f]*:\s*c4194c59\s*lsrc\s*r25,\s*r25,\s*1
+\s*[0-9a-f]*:\s*c40c4d0c\s*xsr\s*r12,\s*r12,\s*1
+\s*[0-9a-f]*:\s*c4778057\s*divs\s*r23,\s*r23,\s*r3
+\s*[0-9a-f]*:\s*c7c18021\s*divu\s*r1,\s*r1,\s*r30
+\s*[0-9a-f]*:\s*c40d020d\s*abs\s*r13,\s*r13
+\s*[0-9a-f]*:\s*c40c620c\s*brev\s*r12,\s*r12
+\s*[0-9a-f]*:\s*c4087c48\s*ff1\s*r8,\s*r8
+\s*[0-9a-f]*:\s*6c46\s*nor\s*r1,\s*r1
+\s*[0-9a-f]*:\s*c6312491\s*nor\s*r17,\s*r17,\s*r17
+\s*[0-9a-f]*:\s*7488\s*zextb\s*r2,\s*r2
+\s*[0-9a-f]*:\s*c41355f3\s*zexth\s*r19,\s*r19
+\s*[0-9a-f]*:\s*c41d58fd\s*sextb\s*r29,\s*r29
+\s*[0-9a-f]*:\s*76ef\s*sexth\s*r11,\s*r11
+\s*[0-9a-f]*:\s*c6210821\s*ixh\s*r1,\s*r1,\s*r17
+\s*[0-9a-f]*:\s*c4370857\s*ixw\s*r23,\s*r23,\s*r1
+#...
+\s*[0-9a-f]*:\s*c4630083\s*subu\s*r3,\s*r3,\s*r3
+\s*[0-9a-f]*:\s*c63f0091\s*subu\s*r17,\s*r31,\s*r17
+\s*[0-9a-f]*:\s*492c\s*lsri\s*r1,\s*r1,\s*12
+\s*[0-9a-f]*:\s*c4554835\s*lsli\s*r21,\s*r21,\s*2
+\s*[0-9a-f]*:\s*c4419421\s*mulsw\s*r1,\s*r1,\s*r2
+\s*[0-9a-f]*:\s*e463207b\s*andi\s*r3,\s*r3,\s*123
+\s*[0-9a-f]*:\s*c5684908\s*rotli\s*r8,\s*r8,\s*11
+\s*[0-9a-f]*:\s*e860fdf8\s*bt\s*0x0.*
+\s*[0-9a-f]*:\s*e840fdf6\s*bf\s*0x0.*
+\s*[0-9a-f]*:\s*e860fdf4\s*bt\s*0x0.*
+\s*[0-9a-f]*:\s*e840fdf2\s*bf\s*0x0.*
+\s*[0-9a-f]*:\s*e800fdf0\s*br\s*0x0.*
+\s*[0-9a-f]*:\s*e800fdee\s*br\s*0x0.*
+\s*[0-9a-f]*:\s*e3fffdec\s*bsr\s*0x0.*
+\s*[0-9a-f]*:\s*cc500000\s*srs\.b\s*r2,\s*\[0x0\].*
+\s*[0-9a-f]*:\s*cc400000\s*lrs\.b\s*r2,\s*\[0x0\].*
+\s*[0-9a-f]*:\s*cc540000\s*srs\.h\s*r2,\s*\[0x0\].*
+\s*[0-9a-f]*:\s*cc440000\s*lrs\.h\s*r2,\s*\[0x0\].*
+\s*[0-9a-f]*:\s*cc580000\s*srs\.w\s*r2,\s*\[0x0\].*
+\s*[0-9a-f]*:\s*cc480000\s*lrs\.w\s*r2,\s*\[0x0\].*
+\s*[0-9a-f]*:\s*ec430002\s*ori\s*r2,\s*r3,\s*2
+\s*[0-9a-f]*:\s*ec43000a\s*ori\s*r2,\s*r3,\s*10
diff --git a/gas/testsuite/gas/csky/cskyv2_all.s b/gas/testsuite/gas/csky/cskyv2_all.s
new file mode 100644
index 0000000..3826b06
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_all.s
@@ -0,0 +1,316 @@
+.text
+all:
+ bkpt
+ movi r3, 22
+ movi r16, 22
+ movi r3, 300
+ lsli r20, r16, 0
+ lsri r8, r2, 20
+ asri r1, r2, 7
+ addc r1, r2
+ addc r17, r1
+ addc r1, r2, r3
+ addc r1, r2, r1
+ addc r1, r17
+ addc r18, r18, r30
+ subc r1, r2
+ subc r17, r1
+ subc r1, r2, r3
+ subc r1, r2, r1
+ subc r1, r17
+ subc r18, r18, r30
+ cmphs r3, r4
+ cmplt r3, r4
+ cmpne r3, r4
+ mvcv r3
+ mvcv r16
+ and r1, r2
+ andn r1, r2
+ tst r3, r4
+ tst r16, r4
+ tstnbz r3
+ tstnbz r16
+ or r18, r23
+ xor r1, r1, r2
+ nor r1, r2, r1
+ mov r2, r3
+ jmp r2
+ jmp r16
+ jsr r2
+ jsr r16
+ rts
+ rts32
+ nop
+ lsl r22, r1
+ lsr r1, r2, r1
+ asr r1, r1, r2
+ rotl r1, r1, r16
+ zextb r2, r3
+ zexth r2, r3
+ sextb r2, r3
+ sexth r2, r3
+ revb r2, r3
+ revh r2, r3
+ revb r16, r3
+ revh r2, r16
+ mult r1, r1, r17
+ mul r4, r7
+ mulsh r7, r18
+ muls.h r2, r8
+ mulsw r30, r30, r1
+ mulsw r1, r2
+ ld.b r2, (r3, 4)
+ ld.h r2, (r3, 4)
+ ld.w r2, (r14, 4)
+ st.b r2, (r3, 4)
+ st.h r2, (r3, 4)
+ st.w r2, (r14, 4)
+ ld.b r8, (r3, 4)
+ ld.h r2, (r8, 4)
+ ld.w r2, (r14, 4)
+ st.b r2, (r8, 4)
+ st.h r2, (r8, 4)
+ st.w r8, (r14, 4)
+ ld.bs r2, (r3, 3)
+ ld.d r2, (r3, 4)
+ st.d r2, (r3, 4)
+ stex.w r2, (r3, 4)
+ ldex.w r2, (r3, 4)
+ addi sp, sp, 0x30
+ addi r3, sp, 0x4
+ addi r1, 20
+ addi r1, r1, 20
+ addi r21, 20
+ addi r1, 0x200
+ addi r2, r4, 1
+ addi r8, r4, 1
+ addi r1, r4, 9
+ addi r1, r28, 9
+ addi r3, sp, 0x1
+ addi r3, sp, 0x400
+ addi sp, sp, 0x33
+ addi sp, sp, 0x200
+ addi16 r1, 20
+ addi16 r2, r4, 1
+ addi32 r2, r4, 1
+ addi32 r3, sp, 0x400
+ addi32 sp, sp, 0x33
+ subi sp, sp, 0x30
+ subi r1, 20
+ subi r1, r1, 20
+ subi r21, 20
+ subi r1, 0x200
+ subi r2, r4, 1
+ subi r8, r4, 1
+ subi r1, r4, 9
+ subi r1, r28, 9
+ subi sp, sp, 0x33
+ subi sp, sp, 0x200
+ subi16 r1, 20
+ subi16 r2, r4, 1
+ subi32 r2, r4, 1
+ subi32 sp, sp, 0x33
+ sub r3, r0
+ sub r8, r0
+ sub r9, r3, r0
+ sub r3, r3, r0
+ sub r9, r9, r0
+ sub r13, r23, r0
+ add r3, r0
+ add r8, r0
+ add r9, r3, r0
+ add r3, r3, r0
+ add r9, r9, r0
+ add r13, r23, r0
+ cmplei r1, 1
+ cmplei r18, 3
+ cmpls r12, r3
+ cmpls r22, r3
+ cmpgt r2, r2
+ cmpgt r25, r2
+ tstle r5
+ tstle r25
+ tstne r2
+ tstne r24
+ tstlt r4
+ tstlt r24
+ setc
+ clrc
+ rotlc r2, 1
+ rotlc r16, 1
+ sce 5
+ trap 2
+ clrf r2
+ clrt r26
+ rte
+ rfi
+ stop
+ wait
+ doze
+ we
+ se
+ mvc r23
+ mfhis r3
+ mflos r17
+ mvtc
+ mfhi r18
+ mthi r19
+ mflo r3
+ mtlo r8
+ sync 0
+ sync 1
+ sync 20
+ idly 0
+ idly 2
+ idly 4
+ idly 5
+ idly 32
+ cprc <1, 1234>
+ cpop <1, 1234>
+ cpwgr r20, <1, 1234>
+ cpwcr r20, <1, 1234>
+ cprgr r20, <1, 1234>
+ cprcr r20, <1, 1234>
+ movi r2, 12
+ movih r2, 16
+ bgeni r2, 12
+ bgeni r2, 16
+ pop r4, r15
+ pop r15, r4-r11
+ pop r28
+ pop r16
+ push r4, r15
+ push r15, r4-r11
+ push r28
+ push r16
+ ins r3, r2, 4, 2
+ zext r3, r2, 4, 2
+ sext r3, r2, 4, 2
+ andi r3, r2, 2
+ andni r3, r2, 2
+ xori r3, r2, 12
+ ldm r3-r5, (r2)
+ stm r3-r5, (r2)
+ rsub r3, r2, r1
+ str.b r3, (r2, r1 << 0)
+ str.h r3, (r2, r1 << 0)
+ str.w r3, (r2, r1 << 0)
+ ldr.b r3, (r2, r1 << 1)
+ ldr.h r3, (r2, r1 << 1)
+ ldr.w r3, (r2, r1 << 1)
+ ldr.bs r2, (r2, r3 << 0)
+ ldr.bs r2, (r2, r3 << 1)
+ ldr.bs r2, (r2, r3 << 2)
+ ldr.bs r2, (r2, r3 << 3)
+ ldr.hs r2, (r2, r3 << 0)
+ ldr.hs r2, (r2, r3 << 1)
+ ldr.hs r2, (r2, r3 << 2)
+ ldr.hs r2, (r2, r3 << 3)
+ xsr r3, r2, 3
+ asrc r3, r2, 3
+ lsrc r3, r2, 3
+ lslc r3, r2, 3
+ rotli r3, r2, 4
+ rotri r1, 32
+ rotri r1, 1
+ rotri r1, r16, 7
+ rotli r1, 31
+ rotli r1, 0
+ rotli r1, r16, 7
+ decne r3, r2, 4
+ declt r3, r2, 4
+ decgt r3, r2, 4
+ dect r3, r2, 4
+ decf r3, r2, 4
+ incf r3, r2, 4
+ inct r3, r2, 4
+ ldq r4-r7, (r3)
+ stq r4-r7, (r3)
+ psrclr ee
+ psrclr af, fe
+ psrset ee, fe, af
+ psrset ie, ee, fe, af
+ abs r17, r20
+ bgenr r3, r21
+ brev r23, r1
+ xtrb0 r5, r3
+ xtrb1 r3, r9
+ xtrb2 r16, r20
+ xtrb3 r11, r24
+ ff0 r2, r21
+ ff1 r18, r1
+ mtcr r2, cr<3, 0>
+ mtcr r2, cr4
+ mtcr r2, vbr
+ mfcr r2, cr<0, 0>
+ mfcr r2, cr0
+ mfcr r2, psr
+ not r2
+ not r16
+ not r2, r16
+ not r2, r2
+ ixh r2, r3, r4
+ ixw r2, r3, r4
+ ixd r2, r3, r4
+ divs r2, r3, r4
+ divu r2, r3, r4
+ movf r1, r2
+ movt r23, r2
+ bmaski r8, 8
+ bmaski r1, 0
+ bmaski r1, 4
+ bmaski r1, 17
+ bmaski r21, 16
+ bmaski r13, 16
+ bmaski r1, 31
+ bmaski r1, 32
+ pldr (r2, 0x8)
+ pldw (r2, 0x8)
+ neg r1
+ rsubi r2, 23
+ asrc r3
+ incf r4
+ inct r13
+ decf r16
+ decgt r17
+ declt r19
+ decne r20
+ dect r31
+ lslc r11
+ lsrc r25
+ xsr r12
+ divs r23, r3
+ divu r1, r30
+ abs r13
+ brev r12
+ ff1 r8
+ not r1
+ not r17
+ zextb r2
+ zexth r19
+ sextb r29
+ sexth r11
+ ixh r1, r17
+ ixw r23, r1
+ rsub r3, r3
+ rsub r17, r31
+ lsri r1, 12
+ lsli r21, 2
+ mulsw r1, r2
+ andi r3, 123
+ rori r8, 21
+ bt all
+ bf all
+ jbt all
+ jbf all
+ br all
+ jbr all
+ bsr all
+ srs.b r2, [all]
+ lrs.b r2, [all]
+ srs.h r2, [all]
+ lrs.h r2, [all]
+ srs.w r2, [all]
+ lrs.w r2, [all]
+ ori r2, r3, 2
+ ori r2, r3, 10
diff --git a/gas/testsuite/gas/csky/cskyv2_dsp.d b/gas/testsuite/gas/csky/cskyv2_dsp.d
new file mode 100644
index 0000000..f2e3d33
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_dsp.d
@@ -0,0 +1,18 @@
+# name: csky - all
+#as: -mcpu=ck810e -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*c4818820\s*mulu\s*r1,\s*r4
+\s*[0-9a-f]*:\s*c6ec8840\s*mulua\s*r12,\s*r23
+\s*[0-9a-f]*:\s*c46f8880\s*mulus\s*r15,\s*r3
+\s*[0-9a-f]*:\s*c4418c20\s*muls\s*r1,\s*r2
+\s*[0-9a-f]*:\s*c4428c40\s*mulsa\s*r2,\s*r2
+\s*[0-9a-f]*:\s*c4638c80\s*mulss\s*r3,\s*r3
+\s*[0-9a-f]*:\s*c6689040\s*mulsha\s*r8,\s*r19
+\s*[0-9a-f]*:\s*c4319080\s*mulshs\s*r17,\s*r1
+\s*[0-9a-f]*:\s*c6ec9440\s*mulswa\s*r12,\s*r23
+\s*[0-9a-f]*:\s*c4a39480\s*mulsws\s*r3,\s*r5
diff --git a/gas/testsuite/gas/csky/cskyv2_dsp.s b/gas/testsuite/gas/csky/cskyv2_dsp.s
new file mode 100644
index 0000000..9c0666c
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_dsp.s
@@ -0,0 +1,11 @@
+.text
+ mulu r1, r4
+ mulua r12, r23
+ mulus r15, r3
+ muls r1, r2
+ mulsa r2, r2
+ mulss r3, r3
+ mulsha r8, r19
+ mulshs r17, r1
+ mulswa r12, r23
+ mulsws r3, r5
diff --git a/gas/testsuite/gas/csky/cskyv2_elrw.d b/gas/testsuite/gas/csky/cskyv2_elrw.d
new file mode 100644
index 0000000..5a52d5a
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_elrw.d
@@ -0,0 +1,10 @@
+# name: cskyv2 - elrw
+#as: -mcpu=ck801 -melrw
+#objdump: -D
+
+.*: +file format .*csky.*
+#...
+\s*[0-9a-f]*:\s*024e\s*lrw\s*r2,\s*0x1234.*
+#...
+\s*[0-9a-f]*:\s*c0004020\s*rte
+\s*[0-9a-f]*:\s*00001234\s*\.long\s*0x00001234
diff --git a/gas/testsuite/gas/csky/cskyv2_elrw.s b/gas/testsuite/gas/csky/cskyv2_elrw.s
new file mode 100644
index 0000000..07f8898
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_elrw.s
@@ -0,0 +1,6 @@
+.text
+ lrw r2, 0x1234
+.rept 351
+ nop
+.endr
+ rte
diff --git a/gas/testsuite/gas/csky/cskyv2_float.d b/gas/testsuite/gas/csky/cskyv2_float.d
new file mode 100644
index 0000000..f1039c9
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_float.d
@@ -0,0 +1,59 @@
+# name: csky - all
+#as: -mcpu=ck810f -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*f4000100\s*fcmpzhss\s*fr0
+\s*[0-9a-f]*:\s*f4010120\s*fcmpzlss\s*fr1
+\s*[0-9a-f]*:\s*f4050140\s*fcmpznes\s*fr5
+\s*[0-9a-f]*:\s*f4080160\s*fcmpzuos\s*fr8
+\s*[0-9a-f]*:\s*f40a0900\s*fcmpzhsd\s*fr10
+\s*[0-9a-f]*:\s*f40d0920\s*fcmpzlsd\s*fr13
+\s*[0-9a-f]*:\s*f40e0940\s*fcmpzned\s*fr14
+\s*[0-9a-f]*:\s*f40f0960\s*fcmpzuod\s*fr15
+\s*[0-9a-f]*:\s*f409008c\s*fmovs\s*fr12,\s*fr9
+\s*[0-9a-f]*:\s*f40000c1\s*fabss\s*fr1,\s*fr0
+\s*[0-9a-f]*:\s*f40100e2\s*fnegs\s*fr2,\s*fr1
+\s*[0-9a-f]*:\s*f4470180\s*fcmphss\s*fr7,\s*fr2
+\s*[0-9a-f]*:\s*f46601a0\s*fcmplts\s*fr6,\s*fr3
+\s*[0-9a-f]*:\s*f48201c0\s*fcmpnes\s*fr2,\s*fr4
+\s*[0-9a-f]*:\s*f4ac01e0\s*fcmpuos\s*fr12,\s*fr5
+\s*[0-9a-f]*:\s*f406032b\s*frecips\s*fr11,\s*fr6
+\s*[0-9a-f]*:\s*f407034a\s*fsqrts\s*fr10,\s*fr7
+\s*[0-9a-f]*:\s*f4080889\s*fmovd\s*fr9,\s*fr8
+\s*[0-9a-f]*:\s*f40908cd\s*fabsd\s*fr13,\s*fr9
+\s*[0-9a-f]*:\s*f40a08ee\s*fnegd\s*fr14,\s*fr10
+\s*[0-9a-f]*:\s*f56f0980\s*fcmphsd\s*fr15,\s*fr11
+\s*[0-9a-f]*:\s*f58009a0\s*fcmpltd\s*fr0,\s*fr12
+\s*[0-9a-f]*:\s*f5a309c0\s*fcmpned\s*fr3,\s*fr13
+\s*[0-9a-f]*:\s*f5c409e0\s*fcmpuod\s*fr4,\s*fr14
+\s*[0-9a-f]*:\s*f40f0b25\s*frecipd\s*fr5,\s*fr15
+\s*[0-9a-f]*:\s*f4080b48\s*fsqrtd\s*fr8,\s*fr8
+\s*[0-9a-f]*:\s*f4031081\s*fmovm\s*fr1,\s*fr3
+\s*[0-9a-f]*:\s*f40d10c3\s*fabsm\s*fr3,\s*fr13
+\s*[0-9a-f]*:\s*f40210ef\s*fnegm\s*fr15,\s*fr2
+\s*[0-9a-f]*:\s*f402180f\s*fstosi.rn\s*fr15,\s*fr2
+\s*[0-9a-f]*:\s*f402182e\s*fstosi.rz\s*fr14,\s*fr2
+\s*[0-9a-f]*:\s*f40f184d\s*fstosi.rpi\s*fr13,\s*fr15
+\s*[0-9a-f]*:\s*f40e186c\s*fstosi.rni\s*fr12,\s*fr14
+\s*[0-9a-f]*:\s*f40d188b\s*fstoui.rn\s*fr11,\s*fr13
+\s*[0-9a-f]*:\s*f40c18aa\s*fstoui.rz\s*fr10,\s*fr12
+\s*[0-9a-f]*:\s*f40b18c9\s*fstoui.rpi\s*fr9,\s*fr11
+\s*[0-9a-f]*:\s*f40a18e8\s*fstoui.rni\s*fr8,\s*fr10
+\s*[0-9a-f]*:\s*f4091907\s*fdtosi.rn\s*fr7,\s*fr9
+\s*[0-9a-f]*:\s*f4081926\s*fdtosi.rz\s*fr6,\s*fr8
+\s*[0-9a-f]*:\s*f4071945\s*fdtosi.rpi\s*fr5,\s*fr7
+\s*[0-9a-f]*:\s*f4061964\s*fdtosi.rni\s*fr4,\s*fr6
+\s*[0-9a-f]*:\s*f4051983\s*fdtoui.rn\s*fr3,\s*fr5
+\s*[0-9a-f]*:\s*f40419a2\s*fdtoui.rz\s*fr2,\s*fr4
+\s*[0-9a-f]*:\s*f40319c1\s*fdtoui.rpi\s*fr1,\s*fr3
+\s*[0-9a-f]*:\s*f40219e0\s*fdtoui.rni\s*fr0,\s*fr2
+\s*[0-9a-f]*:\s*f4011a0e\s*fsitos\s*fr14,\s*fr1
+\s*[0-9a-f]*:\s*f4001a2c\s*fuitos\s*fr12,\s*fr0
+\s*[0-9a-f]*:\s*f4021a8d\s*fsitod\s*fr13,\s*fr2
+\s*[0-9a-f]*:\s*f4041aab\s*fuitod\s*fr11,\s*fr4
+\s*[0-9a-f]*:\s*f4081ac2\s*fdtos\s*fr2,\s*fr8
+\s*[0-9a-f]*:\s*f40b1ae5\s*fstod\s*fr5,\s*fr11
diff --git a/gas/testsuite/gas/csky/cskyv2_float.s b/gas/testsuite/gas/csky/cskyv2_float.s
new file mode 100644
index 0000000..ff73391
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_float.s
@@ -0,0 +1,52 @@
+.text
+fcmpzhss vr0
+fcmpzlss vr1
+fcmpznes vr5
+fcmpzuos vr8
+fcmpzhsd vr10
+fcmpzlsd vr13
+fcmpzned vr14
+fcmpzuod vr15
+fmovs vr12, fr9
+fabss vr1, fr0
+fnegs vr2, fr1
+fcmphss vr7, fr2
+fcmplts vr6, fr3
+fcmpnes vr2, fr4
+fcmpuos vr12, fr5
+frecips vr11, fr6
+fsqrts vr10, fr7
+fmovd vr9, fr8
+fabsd vr13, fr9
+fnegd vr14, fr10
+fcmphsd vr15, fr11
+fcmpltd vr0, fr12
+fcmpned vr3, fr13
+fcmpuod vr4, fr14
+frecipd vr5, fr15
+fsqrtd vr8, fr8
+fmovm vr1, fr3
+fabsm vr3, fr13
+fnegm vr15, fr2
+fstosi.rn vr15, vr2
+fstosi.rz vr14, vr2
+fstosi.rpi vr13, vr15
+fstosi.rni vr12, vr14
+fstoui.rn vr11, fr13
+fstoui.rz vr10, fr12
+fstoui.rpi vr9, fr11
+fstoui.rni fr8, vr10
+fdtosi.rn fr7, vr9
+fdtosi.rz fr6, vr8
+fdtosi.rpi fr5, vr7
+fdtosi.rni fr4, vr6
+fdtoui.rn fr3, fr5
+fdtoui.rz fr2, fr4
+fdtoui.rpi fr1, fr3
+fdtoui.rni fr0, fr2
+fsitos vr14, vr1
+fuitos fr12, vr0
+fsitod fr13, fr2
+fuitod fr11, fr4
+fdtos vr2, vr8
+fstod fr5, vr11
diff --git a/gas/testsuite/gas/csky/cskyv2_lrw.d b/gas/testsuite/gas/csky/cskyv2_lrw.d
new file mode 100644
index 0000000..5b8ea04
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_lrw.d
@@ -0,0 +1,19 @@
+# name: cskyv2 - lrw
+#as: -mcpu=ck810 -W
+#objdump: -D
+
+.*: +file format .*csky.*
+#...
+00000000 <LRW>:
+\s*[0-9a-f]*:\s*ea020100\s*movi\s*r2,\s*256
+\s*[0-9a-f]*:\s*ea021000\s*movi\s*r2,\s*4096
+\s*[0-9a-f]*:\s*ea220001\s*movih\s*r2,\s*1
+\s*[0-9a-f]*:\s*1042\s*lrw\s*r2,\s*0x12341234.*
+\s*[0-9a-f]*:\s*1043\s*lrw\s*r2,\s*0x0.*
+\s*[0-9a-f]*:\s*1041\s*lrw\s*r2,\s*0x12341234.*
+#...
+00000012 <L1>:
+\s*[0-9a-f]*:\s*6c8f\s*mov\s*r2,\s*r3
+\s*[0-9a-f]*:\s*12341234\s*\.long\s*0x12341234
+\s*[0-9a-f]*:\s*00000000\s*\.long\s*0x00000000
+#...
diff --git a/gas/testsuite/gas/csky/cskyv2_lrw.s b/gas/testsuite/gas/csky/cskyv2_lrw.s
new file mode 100644
index 0000000..0ff6070
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_lrw.s
@@ -0,0 +1,11 @@
+.text
+LRW:
+ lrw r2, 0x100
+ lrw16 r2, 0x1000
+ lrw32 r2, 0x10000
+ lrw r2, 0x12341234
+ lrw r2, L1
+ lrw r2, [L1]
+
+L1:
+ mov r2, r3
diff --git a/gas/testsuite/gas/csky/cskyv2_mnolrw1.d b/gas/testsuite/gas/csky/cskyv2_mnolrw1.d
new file mode 100644
index 0000000..8714677
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_mnolrw1.d
@@ -0,0 +1,23 @@
+# name: cskyv2 - nolrw
+#as: -mcpu=ck810 -mnolrw -W
+#objdump: -D
+
+.*: +file format .*csky.*
+#...
+00000000 <LRW>:
+\s*[0-9a-f]*:\s*ea220000\s*movih\s*r2,\s*0
+\s*[0-9a-f]*:\s*ec420100\s*ori\s*r2,\s*r2,\s*256
+\s*[0-9a-f]*:\s*ea220000\s*movih\s*r2,\s*0
+\s*[0-9a-f]*:\s*ec421000\s*ori\s*r2,\s*r2,\s*4096
+\s*[0-9a-f]*:\s*ea220001\s*movih\s*r2,\s*1
+\s*[0-9a-f]*:\s*ec420000\s*ori\s*r2,\s*r2,\s*0
+\s*[0-9a-f]*:\s*ea221234\s*movih\s*r2,\s*4660
+\s*[0-9a-f]*:\s*ec421234\s*ori\s*r2,\s*r2,\s*4660
+\s*[0-9a-f]*:\s*ea220000\s*movih\s*r2,\s*0
+\s*[0-9a-f]*:\s*ec420000\s*ori\s*r2,\s*r2,\s*0
+\s*[0-9a-f]*:\s*ea220000\s*movih\s*r2,\s*0
+\s*[0-9a-f]*:\s*ec420000\s*ori\s*r2,\s*r2,\s*0
+#...
+00000030 <L1>:
+\s*[0-9a-f]*:\s*6c8f\s*mov\s*r2,\s*r3
+#...
diff --git a/gas/testsuite/gas/csky/cskyv2_mnolrw1.s b/gas/testsuite/gas/csky/cskyv2_mnolrw1.s
new file mode 100644
index 0000000..0ff6070
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_mnolrw1.s
@@ -0,0 +1,11 @@
+.text
+LRW:
+ lrw r2, 0x100
+ lrw16 r2, 0x1000
+ lrw32 r2, 0x10000
+ lrw r2, 0x12341234
+ lrw r2, L1
+ lrw r2, [L1]
+
+L1:
+ mov r2, r3
diff --git a/gas/testsuite/gas/csky/cskyv2_mnolrw2.d b/gas/testsuite/gas/csky/cskyv2_mnolrw2.d
new file mode 100644
index 0000000..2232e76
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_mnolrw2.d
@@ -0,0 +1,12 @@
+# name: csky - nolrw
+#as: -mcpu=ck810 -mnolrw -W
+#readelf: -r --wide
+
+
+Relocation section '.rela.text\' at offset .* contains 4 entries:
+#...
+00000020.*R_CKCORE_ADDR_HI16\s*00000030\s*L1\s*\+\s*0
+00000024.*R_CKCORE_ADDR_LO16\s*00000030\s*L1\s*\+\s*0
+00000028.*R_CKCORE_ADDR_HI16\s*00000030\s*L1\s*\+\s*0
+0000002c.*R_CKCORE_ADDR_LO16\s*00000030\s*L1\s*\+\s*0
+#pass
diff --git a/gas/testsuite/gas/csky/cskyv2_mnolrw2.s b/gas/testsuite/gas/csky/cskyv2_mnolrw2.s
new file mode 100644
index 0000000..0ff6070
--- /dev/null
+++ b/gas/testsuite/gas/csky/cskyv2_mnolrw2.s
@@ -0,0 +1,11 @@
+.text
+LRW:
+ lrw r2, 0x100
+ lrw16 r2, 0x1000
+ lrw32 r2, 0x10000
+ lrw r2, 0x12341234
+ lrw r2, L1
+ lrw r2, [L1]
+
+L1:
+ mov r2, r3
diff --git a/gas/testsuite/gas/csky/enhance_dsp.d b/gas/testsuite/gas/csky/enhance_dsp.d
new file mode 100644
index 0000000..4317038
--- /dev/null
+++ b/gas/testsuite/gas/csky/enhance_dsp.d
@@ -0,0 +1,217 @@
+#name: csky - enhancedsp
+#as: -mcpu=ck803er1
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*d0038002\s*ldbi.b\s*r2,\s*\(r3\)
+\s*[0-9a-f]*:\s*d0038402\s*ldbi.h\s*r2,\s*\(r3\)
+\s*[0-9a-f]*:\s*d0038802\s*ldbi.w\s*r2,\s*\(r3\)
+#...
+\s*[0-9a-f]*:\s*e9c20ffa\s*bloop\s*r2,\s*0x0,\s*0xc.*
+\s*[0-9a-f]*:\s*d0038c02\s*pldbi.d\s*r2,\s*\(r3\)
+\s*[0-9a-f]*:\s*d0039002\s*ldbi.hs\s*r2,\s*\(r3\)
+\s*[0-9a-f]*:\s*d0039402\s*ldbi.bs\s*r2,\s*\(r3\)
+\s*[0-9a-f]*:\s*d4038002\s*stbi.b\s*r2,\s*\(r3\)
+\s*[0-9a-f]*:\s*d4038402\s*stbi.h\s*r2,\s*\(r3\)
+\s*[0-9a-f]*:\s*d4038802\s*stbi.w\s*r2,\s*\(r3\)
+\s*[0-9a-f]*:\s*d083a002\s*ldbir.b\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*d083a402\s*ldbir.h\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*d083a802\s*ldbir.w\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*d083ac02\s*pldbir.d\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*d083b402\s*ldbir.hs\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*d083b002\s*ldbir.bs\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*d483a002\s*stbir.b\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*d483a402\s*stbir.h\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*d483a802\s*stbir.w\s*r2,\s*\(r3\),\s*r4
+\s*[0-9a-f]*:\s*f883c042\s*padd\.8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c002\s*padd\.16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c142\s*padd\.u8\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c1c2\s*padd\.s8\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c102\s*padd\.u16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c182\s*padd\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c122\s*add\.u32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c1a2\s*add\.s32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c442\s*psub\.8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c402\s*psub\.16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c542\s*psub\.u8\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c5c2\s*psub\.s8\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c502\s*psub\.u16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c582\s*psub\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c522\s*sub\.u32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c5a2\s*sub\.s32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c242\s*paddh\.u8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c2c2\s*paddh\.s8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c202\s*paddh\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c282\s*paddh\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c222\s*addh\.u32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c2a2\s*addh\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c642\s*psubh\.u8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c6c2\s*psubh\.s8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c602\s*psubh\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c682\s*psubh\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c622\s*subh\.u32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c6a2\s*subh\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c862\s*pasx\.16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cc62\s*psax\.16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c9e2\s*pasx\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c962\s*pasx\.u16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cd62\s*psax\.u16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cde2\s*psax\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883ca62\s*pasxh\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cae2\s*pasxh\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883ce62\s*psaxh\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cee2\s*psaxh\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c842\s*pcmpne\.8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c802\s*pcmpne\.16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c942\s*pcmphs\.u8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c982\s*pcmphs\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c902\s*pcmphs\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883c9c2\s*pcmphs\.s8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883ca42\s*pcmplt\.u8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883ca02\s*pcmplt\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883ca82\s*pcmplt\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883ca02\s*pcmplt\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cc42\s*pmax\.u8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883ccc2\s*pmax\.s8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cc02\s*pmax\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cc82\s*pmax\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cc22\s*max\.u32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cca2\s*max\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cd42\s*pmin\.u8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cdc2\s*pmin\.s8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cd02\s*pmin\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cd82\s*pmin\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cd22\s*min\.u32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883cda2\s*min\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8229083\s*sel\s*r3,\s*r2,\s*r1,\s*r4
+\s*[0-9a-f]*:\s*f883e042\s*psabsa\.u8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883e142\s*psabsaa\.u8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883e262\s*divul\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883e2e2\s*divsl\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883e4c2\s*mulaca\.s8\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f9e3d1a2\s*asri\.s32\.r\s*r2,\s*r3,\s*16
+\s*[0-9a-f]*:\s*f8c3d1e2\s*asr\.s32\.r\s*r2,\s*r3,\s*r6
+\s*[0-9a-f]*:\s*f9e3d322\s*lsri\.u32\.r\s*r2,\s*r3,\s*16
+\s*[0-9a-f]*:\s*f8c3d362\s*lsr\.u32\.r\s*r2,\s*r3,\s*r6
+\s*[0-9a-f]*:\s*f9e3d522\s*lsli\.u32\.s\s*r2,\s*r3,\s*16
+\s*[0-9a-f]*:\s*f9e3d5a2\s*lsli\.s32\.s\s*r2,\s*r3,\s*16
+\s*[0-9a-f]*:\s*f8c3d562\s*lsl\.u32\.s\s*r2,\s*r3,\s*r6
+\s*[0-9a-f]*:\s*f8c3d5e2\s*lsl\.s32\.s\s*r2,\s*r3,\s*r6
+\s*[0-9a-f]*:\s*f8e3d082\s*pasri\.s16\s*r2,\s*r3,\s*8
+\s*[0-9a-f]*:\s*f8c3d0c2\s*pasr\.s16\s*r2,\s*r3,\s*r6
+\s*[0-9a-f]*:\s*f8e3d182\s*pasri\.s16\.r\s*r2,\s*r3,\s*8
+\s*[0-9a-f]*:\s*f8c3d1c2\s*pasr\.s16\.r\s*r2,\s*r3,\s*r6
+\s*[0-9a-f]*:\s*f8e3d202\s*plsri\.u16\s*r2,\s*r3,\s*8
+\s*[0-9a-f]*:\s*f883d242\s*plsr\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8e3d302\s*plsri\.u16\.r\s*r2,\s*r3,\s*8
+\s*[0-9a-f]*:\s*f883d342\s*plsr\.u16\.r\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8e3d402\s*plsli\.u16\s*r2,\s*r3,\s*8
+\s*[0-9a-f]*:\s*fa03d442\s*plsl\.u16\s*r2,\s*r3,\s*r16
+\s*[0-9a-f]*:\s*f8e3d502\s*plsli\.u16\.s\s*r2,\s*r3,\s*8
+\s*[0-9a-f]*:\s*f8e3d582\s*plsli\.s16\.s\s*r2,\s*r3,\s*8
+\s*[0-9a-f]*:\s*f883d542\s*plsl\.u16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883d5c2\s*plsl\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8a3a482\s*pkg\s*r2,\s*r3,\s*4,\s*r5,\s*3
+\s*[0-9a-f]*:\s*f8839882\s*dexti\s*r2,\s*r3,\s*r4,\s*4
+\s*[0-9a-f]*:\s*f8839ca2\s*dext\s*r2,\s*r3,\s*r4,\s*r5
+\s*[0-9a-f]*:\s*f883d842\s*pkgll\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883d862\s*pkghh\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f803d902\s*pext\.u8\.e\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803d982\s*pext\.s8\.e\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803d922\s*pextx\.u8\.e\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803d9a2\s*pextx\.s8\.e\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f883da02\s*narl\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883da22\s*narh\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883da42\s*narlx\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883da62\s*narhx\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*fa03db02\s*clipi\.u32\s*r2,\s*r3,\s*16
+\s*[0-9a-f]*:\s*f9e3db82\s*clipi\.s32\s*r2,\s*r3,\s*16
+\s*[0-9a-f]*:\s*f883db22\s*clip\.u32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883dba2\s*clip\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f863dbc2\s*pclipi\.s16\s*r2,\s*r3,\s*4
+\s*[0-9a-f]*:\s*f883db42\s*pclipi\.u16\s*r2,\s*r3,\s*4
+\s*[0-9a-f]*:\s*f883dbe2\s*pclip\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f883db62\s*pclip\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f803dc82\s*pabs\.s8\.s\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803dca2\s*pabs\.s16\.s\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803dcc2\s*abs\.s32\.s\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803dd82\s*pneg\.s8\.s\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803dda2\s*pneg\.s16\.s\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803ddc2\s*neg\.s32\.s\s*r2,\s*r3
+\s*[0-9a-f]*:\s*f803de62\s*dup\.8\s*r2,\s*r3,\s*3
+\s*[0-9a-f]*:\s*f803df02\s*dup\.16\s*r2,\s*r3,\s*0
+\s*[0-9a-f]*:\s*f8838002\s*mul\.u32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838202\s*mul\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838082\s*mula\.u32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838282\s*mula\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88380c2\s*muls\.u32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88382c2\s*muls\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838182\s*mula\.u32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838382\s*mula\.s32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88381c2\s*muls\.u32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88383c2\s*muls\.s32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838402\s*mul\.s32\.h\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838602\s*mul\.s32\.rh\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838502\s*rmul\.s32\.h\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838702\s*rmul\.s32\.rh\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838582\s*mula\.s32\.hs\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88385c2\s*muls\.s32\.hs\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838782\s*mula\.s32\.rhs\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88387c2\s*muls\.s32\.rhs\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838802\s*mulxl\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838a02\s*mulxl\.s32\.r\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838c02\s*mulxh\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838e02\s*mulxh\.s32\.r\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838902\s*rmulxl\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838b02\s*rmulxl\.s32\.r\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838d02\s*rmulxh\.s32\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838f02\s*rmulxh\.s32\.r\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838982\s*mulaxl\.s32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838b82\s*mulaxl\.s32\.rs\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838d82\s*mulaxh\.s32\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838f82\s*mulaxh\.s32\.rs\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838022\s*mulll\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838262\s*mulhh\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838222\s*mulhl\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838122\s*rmulll\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838362\s*rmulhh\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838322\s*rmulhl\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88381a2\s*mulall\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88383e2\s*mulahh\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88383a2\s*mulahl\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88380a2\s*mulall\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88382e2\s*mulahh\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88380e2\s*mulahl\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88384a2\s*pmul\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88384e2\s*pmulx\.u16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838422\s*pmul\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838462\s*pmulx\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838522\s*prmul\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838562\s*prmulx\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88385a2\s*prmul\.s16\.h\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88387a2\s*prmul\.s16\.rh\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88385e2\s*prmulx\.s16\.h\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88387e2\s*prmulx\.s16\.rh\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838922\s*mulca\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838962\s*mulcax\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838a22\s*mulcs\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838a62\s*mulcsr\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838c22\s*mulcsx\.s16\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88389a2\s*mulaca\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88389e2\s*mulacax\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838ba2\s*mulacs\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838be2\s*mulacsr\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838da2\s*mulacsx\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838de2\s*mulsca\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838fa2\s*mulscax\.s16\.s\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88388a2\s*mulaca\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f88388e2\s*mulacax\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838aa2\s*mulacs\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838ae2\s*mulacsr\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838ca2\s*mulacsx\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838ce2\s*mulsca\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838ce2\s*mulsca\.s16\.e\s*r2,\s*r3,\s*r4
+\s*[0-9a-f]*:\s*f8838442\s*mula\.32\.l\s*r2,\s*r3,\s*r4
diff --git a/gas/testsuite/gas/csky/enhance_dsp.s b/gas/testsuite/gas/csky/enhance_dsp.s
new file mode 100644
index 0000000..0491a53
--- /dev/null
+++ b/gas/testsuite/gas/csky/enhance_dsp.s
@@ -0,0 +1,219 @@
+
+.text
+hello:
+.loop_start:
+ ldbi.b r2, (r3)
+ ldbi.h r2, (r3)
+ ldbi.w r2, (r3)
+.loop_end:
+ bloop r2, .loop_start, .loop_end
+ pldbi.d r2, (r3)
+ ldbi.hs r2, (r3)
+ ldbi.bs r2, (r3)
+ stbi.b r2, (r3)
+ stbi.h r2, (r3)
+ stbi.w r2, (r3)
+ ldbir.b r2, (r3), r4
+ ldbir.h r2, (r3), r4
+ ldbir.w r2, (r3), r4
+ pldbir.d r2, (r3), r4
+ ldbir.hs r2, (r3), r4
+ ldbir.bs r2, (r3), r4
+ stbir.b r2, (r3), r4
+ stbir.h r2, (r3), r4
+ stbir.w r2, (r3), r4
+
+ padd.8 r2, r3, r4
+ padd.16 r2, r3, r4
+ padd.u8.s r2, r3, r4
+ padd.s8.s r2, r3, r4
+ padd.u16.s r2, r3, r4
+ padd.s16.s r2, r3, r4
+ add.u32.s r2, r3, r4
+ add.s32.s r2, r3, r4
+ psub.8 r2, r3, r4
+ psub.16 r2, r3, r4
+ psub.u8.s r2, r3, r4
+ psub.s8.s r2, r3, r4
+ psub.u16.s r2, r3, r4
+ psub.s16.s r2, r3, r4
+ sub.u32.s r2, r3, r4
+ sub.s32.s r2, r3, r4
+ paddh.u8 r2, r3, r4
+ paddh.s8 r2, r3, r4
+ paddh.u16 r2, r3, r4
+ paddh.s16 r2, r3, r4
+ addh.u32 r2, r3, r4
+ addh.s32 r2, r3, r4
+ psubh.u8 r2, r3, r4
+ psubh.s8 r2, r3, r4
+ psubh.u16 r2, r3, r4
+ psubh.s16 r2, r3, r4
+ subh.u32 r2, r3, r4
+ subh.s32 r2, r3, r4
+
+ pasx.16 r2, r3, r4
+ psax.16 r2, r3, r4
+ pasx.s16.s r2, r3, r4
+ pasx.u16.s r2, r3, r4
+ psax.u16.s r2, r3, r4
+ psax.s16.s r2, r3, r4
+ pasxh.u16 r2, r3, r4
+ pasxh.s16 r2, r3, r4
+ psaxh.u16 r2, r3, r4
+ psaxh.s16 r2, r3, r4
+ pcmpne.8 r2, r3, r4
+ pcmpne.16 r2, r3, r4
+ pcmphs.u8 r2, r3, r4
+ pcmphs.s16 r2, r3, r4
+ pcmphs.u16 r2, r3, r4
+ pcmphs.s8 r2, r3, r4
+ pcmplt.u8 r2, r3, r4
+ pcmplt.u16 r2, r3, r4
+ pcmplt.s16 r2, r3, r4
+ pcmplt.u16 r2, r3, r4
+ pmax.u8 r2, r3, r4
+ pmax.s8 r2, r3, r4
+ pmax.u16 r2, r3, r4
+ pmax.s16 r2, r3, r4
+ max.u32 r2, r3, r4
+ max.s32 r2, r3, r4
+ pmin.u8 r2, r3, r4
+ pmin.s8 r2, r3, r4
+ pmin.u16 r2, r3, r4
+ pmin.s16 r2, r3, r4
+ min.u32 r2, r3, r4
+ min.s32 r2, r3, r4
+ sel r3, r2, r1, r4
+
+ psabsa.u8 r2, r3, r4
+ psabsaa.u8 r2, r3, r4
+ divul r2, r3, r4
+ divsl r2, r3, r4
+ mulaca.s8 r2, r3, r4
+
+ asri.s32.r r2, r3, 16
+ asr.s32.r r2, r3, r6
+ lsri.u32.r r2, r3, 16
+ lsr.u32.r r2, r3, r6
+ lsli.u32.s r2, r3, 16
+ lsli.s32.s r2, r3, 16
+ lsl.u32.s r2, r3, r6
+ lsl.s32.s r2, r3, r6
+ pasri.s16 r2, r3, 8
+ pasr.s16 r2, r3, r6
+ pasri.s16.r r2, r3, 8
+ pasr.s16.r r2, r3, r6
+ plsri.u16 r2, r3, 8
+ plsr.u16 r2, r3, r4
+ plsri.u16.r r2, r3, 8
+ plsr.u16.r r2, r3, r4
+ plsli.u16 r2, r3, 8
+ plsl.u16 r2, r3, r16
+ plsli.u16.s r2, r3, 8
+ plsli.s16.s r2, r3, 8
+ plsl.u16.s r2, r3, r4
+ plsl.s16.s r2, r3, r4
+
+ pkg r2, r3, 4, r5, 3
+ dexti r2, r3, r4, 4
+ dext r2, r3, r4, r5
+ pkgll r2, r3, r4
+ pkghh r2, r3, r4
+ pext.u8.e r2, r3
+ pext.s8.e r2, r3
+ pextx.u8.e r2, r3
+ pextx.s8.e r2, r3
+ narl r2, r3, r4
+ narh r2, r3, r4
+ narlx r2, r3, r4
+ narhx r2, r3, r4
+ clipi.u32 r2, r3, 16
+ clipi.s32 r2, r3, 16
+ clip.u32 r2, r3, r4
+ clip.s32 r2, r3, r4
+ pclipi.s16 r2, r3, 4
+ pclipi.u16 r2, r3, 4
+ pclip.s16 r2, r3, r4
+ pclip.u16 r2, r3, r4
+ pabs.s8.s r2, r3
+ pabs.s16.s r2, r3
+ abs.s32.s r2, r3
+ pneg.s8.s r2, r3
+ pneg.s16.s r2, r3
+ neg.s32.s r2, r3
+ dup.8 r2, r3, 3
+ dup.16 r2, r3, 0
+
+ mul.u32 r2, r3, r4
+ mul.s32 r2, r3, r4
+ mula.u32 r2, r3, r4
+ mula.s32 r2, r3, r4
+ muls.u32 r2, r3, r4
+ muls.s32 r2, r3, r4
+ mula.u32.s r2, r3, r4
+ mula.s32.s r2, r3, r4
+ muls.u32.s r2, r3, r4
+ muls.s32.s r2, r3, r4
+ mul.s32.h r2, r3, r4
+ mul.s32.rh r2, r3, r4
+ rmul.s32.h r2, r3, r4
+ rmul.s32.rh r2, r3, r4
+ mula.s32.hs r2, r3, r4
+ muls.s32.hs r2, r3, r4
+ mula.s32.rhs r2, r3, r4
+ muls.s32.rhs r2, r3, r4
+ mulxl.s32 r2, r3, r4
+ mulxl.s32.r r2, r3, r4
+ mulxh.s32 r2, r3, r4
+ mulxh.s32.r r2, r3, r4
+ rmulxl.s32 r2, r3, r4
+ rmulxl.s32.r r2, r3, r4
+ rmulxh.s32 r2, r3, r4
+ rmulxh.s32.r r2, r3, r4
+ mulaxl.s32.s r2, r3, r4
+ mulaxl.s32.rs r2, r3, r4
+ mulaxh.s32.s r2, r3, r4
+ mulaxh.s32.rs r2, r3, r4
+ mulll.s16 r2, r3, r4
+ mulhh.s16 r2, r3, r4
+ mulhl.s16 r2, r3, r4
+ rmulll.s16 r2, r3, r4
+ rmulhh.s16 r2, r3, r4
+ rmulhl.s16 r2, r3, r4
+ mulall.s16.s r2, r3, r4
+ mulahh.s16.s r2, r3, r4
+ mulahl.s16.s r2, r3, r4
+ mulall.s16.e r2, r3, r4
+ mulahh.s16.e r2, r3, r4
+ mulahl.s16.e r2, r3, r4
+ pmul.u16 r2, r3, r4
+ pmulx.u16 r2, r3, r4
+ pmul.s16 r2, r3, r4
+ pmulx.s16 r2, r3, r4
+ prmul.s16 r2, r3, r4
+ prmulx.s16 r2, r3, r4
+ prmul.s16.h r2, r3, r4
+ prmul.s16.rh r2, r3, r4
+ prmulx.s16.h r2, r3, r4
+ prmulx.s16.rh r2, r3, r4
+ mulca.s16.s r2, r3, r4
+ mulcax.s16.s r2, r3, r4
+ mulcs.s16 r2, r3, r4
+ mulcsr.s16 r2, r3, r4
+ mulcsx.s16 r2, r3, r4
+ mulaca.s16.s r2, r3, r4
+ mulacax.s16.s r2, r3, r4
+ mulacs.s16.s r2, r3, r4
+ mulacsr.s16.s r2, r3, r4
+ mulacsx.s16.s r2, r3, r4
+ mulsca.s16.s r2, r3, r4
+ mulscax.s16.s r2, r3, r4
+ mulaca.s16.e r2, r3, r4
+ mulacax.s16.e r2, r3, r4
+ mulacs.s16.e r2, r3, r4
+ mulacsr.s16.e r2, r3, r4
+ mulacsx.s16.e r2, r3, r4
+ mulsca.s16.e r2, r3, r4
+ mulsca.s16.e r2, r3, r4
+ mula.32.l r2, r3, r4
diff --git a/gas/testsuite/gas/csky/java.d b/gas/testsuite/gas/csky/java.d
new file mode 100644
index 0000000..f433d52
--- /dev/null
+++ b/gas/testsuite/gas/csky/java.d
@@ -0,0 +1,12 @@
+# name: csky - java
+#as: -mcpu=ck802j
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]:\s*14ac\s*bpop\.h\s*r3
+\s*[0-9a-f]:\s*14ae\s*bpop\.w\s*r3
+\s*[0-9a-f]:\s*14ec\s*bpush\.h\s*r3
+\s*[0-9a-f]:\s*14ee\s*bpush\.w\s*r3
diff --git a/gas/testsuite/gas/csky/java.s b/gas/testsuite/gas/csky/java.s
new file mode 100644
index 0000000..c192750
--- /dev/null
+++ b/gas/testsuite/gas/csky/java.s
@@ -0,0 +1,6 @@
+.text
+hello:
+ bpop.h r3
+ bpop.w r3
+ bpush.h r3
+ bpush.w r3
diff --git a/gas/testsuite/gas/csky/jbsr.d b/gas/testsuite/gas/csky/jbsr.d
new file mode 100644
index 0000000..c036910
--- /dev/null
+++ b/gas/testsuite/gas/csky/jbsr.d
@@ -0,0 +1,14 @@
+# name: jbsr - csky
+#as: -mcpu=ck610
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*ffff\s*bsr\s*0x0.*
+\s*[0-9a-f]*:\s*f7ff\s*br\s*0x2.*
+\s*[0-9a-f]*:\s*f7ff\s*br\s*0x4.*
+\s*[0-9a-f]*:\s*1200\s*\.short\s*0x1200.*
+\s*[0-9a-f]*:\s*00000000\s*\.long\s*0x00000000.*
+#...
diff --git a/gas/testsuite/gas/csky/jbsr.s b/gas/testsuite/gas/csky/jbsr.s
new file mode 100644
index 0000000..860431a
--- /dev/null
+++ b/gas/testsuite/gas/csky/jbsr.s
@@ -0,0 +1,3 @@
+.text
+hello:
+ jbsr hello
diff --git a/gas/testsuite/gas/csky/jbt.d b/gas/testsuite/gas/csky/jbt.d
new file mode 100644
index 0000000..098bdc2
--- /dev/null
+++ b/gas/testsuite/gas/csky/jbt.d
@@ -0,0 +1,16 @@
+# name: jbt - csky
+#as: -mcpu=ck610
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*e7ff\s*bt\s*0x0.*
+\s*[0-9a-f]*:\s*e804\s*bf\s*0xc.*
+\s*[0-9a-f]*:\s*7001\s*jmpi\s*0x0.*
+\s*[0-9a-f]*:\s*0000\s*bkpt\s*
+\s*[0-9a-f]*:\s*0000\s*bkpt\s*
+\s*[0-9a-f]*:\s*0000\s*bkpt\s*
+\s*[0-9a-f]*:\s*1200\s*mov\s*r0,\s*r0
+#...
diff --git a/gas/testsuite/gas/csky/jbt.s b/gas/testsuite/gas/csky/jbt.s
new file mode 100644
index 0000000..10808df
--- /dev/null
+++ b/gas/testsuite/gas/csky/jbt.s
@@ -0,0 +1,10 @@
+.text
+hello:
+ jbt hello
+ jbt label
+.rept 33*1024
+ nop
+.endr
+
+label:
+ nop
diff --git a/gas/testsuite/gas/csky/jbt_pic.d b/gas/testsuite/gas/csky/jbt_pic.d
new file mode 100644
index 0000000..932cd7d
--- /dev/null
+++ b/gas/testsuite/gas/csky/jbt_pic.d
@@ -0,0 +1,23 @@
+# name: jbt - csky
+#as: -mcpu=ck610 -fpic
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*e7ff\s*bt\s*0x0.*
+\s*[0-9a-f]*:\s*e80b\s*bf\s*0x1a.*
+\s*[0-9a-f]*:\s*2470\s*subi\s*r0,\s*r0,\s*8
+\s*[0-9a-f]*:\s*9f00\s*st.w\s*r15,\s*\(r0,\s*0x0\)
+\s*[0-9a-f]*:\s*f800\s*bsr\s*0xa.*
+\s*[0-9a-f]*:\s*7102\s*lrw\s*r1,\s*0x10810.*
+\s*[0-9a-f]*:\s*1cf1\s*addu\s*r1,\s*r1,\s*r15
+\s*[0-9a-f]*:\s*8f00\s*ld.w\s*r15,\s*\(r0,\s*0x0\)
+\s*[0-9a-f]*:\s*2070\s*addi\s*r0,\s*r0,\s*8
+\s*[0-9a-f]*:\s*00c1\s*jmp\s*r1
+\s*[0-9a-f]*:\s*0810\s*cprgr\s*r0,\s*cpr1
+\s*[0-9a-f]*:\s*0001\s*sync
+\s*[0-9a-f]*:\s*0000\s*bkpt
+\s*[0-9a-f]*:\s*1200\s*mov\s*r0,\s*r0
+#...
diff --git a/gas/testsuite/gas/csky/jbt_pic.s b/gas/testsuite/gas/csky/jbt_pic.s
new file mode 100644
index 0000000..10808df
--- /dev/null
+++ b/gas/testsuite/gas/csky/jbt_pic.s
@@ -0,0 +1,10 @@
+.text
+hello:
+ jbt hello
+ jbt label
+.rept 33*1024
+ nop
+.endr
+
+label:
+ nop
diff --git a/gas/testsuite/gas/csky/jmpi1.d b/gas/testsuite/gas/csky/jmpi1.d
new file mode 100644
index 0000000..3cd1211
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpi1.d
@@ -0,0 +1,16 @@
+# name: jmpi1 - csky
+#as: -mcpu=ck610
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]:\s*0000\s*bkpt\s*
+\s*[0-9a-f]:\s*70[0-9a-f]*\s*jmpi\s*0x0\s*\/\/\s*from\s*address\s*pool\s*at\s*0x[0-9a-f]*
+\s*[0-9a-f]:\s*0000\s*bkpt\s*
+\s*[0-9a-f]:\s*f7ff\s*br\s*0x[0-9a-f]*\s*\/\/\s*[0-9a-f]*\s*\<LABEL\+0x[0-9a-f]*\>
+\s*[0-9a-f]:\s*f7ff\s*br\s*0x[0-9a-f]*\s*\/\/\s*[0-9a-f]*\s*\<LABEL\+0x[0-9a-f]*\>
+\s*[0-9a-f]:\s*1200\s*\.short\s*0x1200
+\s*[0-9a-f]:\s*00000000\s*\.long\s*0x00000000
+#...
diff --git a/gas/testsuite/gas/csky/jmpi1.s b/gas/testsuite/gas/csky/jmpi1.s
new file mode 100644
index 0000000..c7ad604
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpi1.s
@@ -0,0 +1,6 @@
+.text
+
+LABEL:
+ bkpt
+ jmpi LABEL
+ bkpt
diff --git a/gas/testsuite/gas/csky/jmpi2.d b/gas/testsuite/gas/csky/jmpi2.d
new file mode 100644
index 0000000..5d855cf
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpi2.d
@@ -0,0 +1,14 @@
+# name: jmpi2 - csky
+#as: -mcpu=ck610
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]:\s*0000\s*bkpt\s*
+\s*[0-9a-f]:\s*70[0-9a-f]*\s*jmpi\s*0x0\s*\/\/\s*from\s*address\s*pool\s*at\s*0x[0-9a-f]*
+\s*[0-9a-f]:\s*f7ff\s*br\s*0x[0-9a-f]*\s*\/\/\s*[0-9a-f]*\s*\<LABEL\+0x[0-9a-f]*\>
+\s*[0-9a-f]:\s*f7ff\s*br\s*0x[0-9a-f]*\s*\/\/\s*[0-9a-f]*\s*\<LABEL\+0x[0-9a-f]*\>
+\s*[0-9a-f]:\s*00000000\s*\.long\s*0x00000000
+#...
diff --git a/gas/testsuite/gas/csky/jmpi2.s b/gas/testsuite/gas/csky/jmpi2.s
new file mode 100644
index 0000000..91e209f
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpi2.s
@@ -0,0 +1,5 @@
+.text
+
+LABEL:
+ bkpt
+ jmpi LABEL2
diff --git a/gas/testsuite/gas/csky/jmpi3.d b/gas/testsuite/gas/csky/jmpi3.d
new file mode 100644
index 0000000..c19b04f
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpi3.d
@@ -0,0 +1,9 @@
+# name: jmpi2 - csky
+#as: -mcpu=ck610
+#readelf: -r --wide
+
+
+Relocation section '.rela.text\' at offset .* contains 1 entry:
+#...
+.*R_CKCORE_ADDR32[ \t]+00000000[ \t]+\.text \+[ \t]+[0-9a-f]+
+#pass
diff --git a/gas/testsuite/gas/csky/jmpi3.s b/gas/testsuite/gas/csky/jmpi3.s
new file mode 100644
index 0000000..c7ad604
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpi3.s
@@ -0,0 +1,6 @@
+.text
+
+LABEL:
+ bkpt
+ jmpi LABEL
+ bkpt
diff --git a/gas/testsuite/gas/csky/jmpiv2_1.d b/gas/testsuite/gas/csky/jmpiv2_1.d
new file mode 100644
index 0000000..d8006e7
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpiv2_1.d
@@ -0,0 +1,13 @@
+# name: jmpiv2_1 - csky
+#as: -mcpu=ck810
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]:\s*0000\s*bkpt\s*
+\s*[0-9a-f]:\s*eac00002\s*jmpi\s*0x0\s*\/\/\s*from\s*address\s*pool\s*at\s*0x[0-9a-f]*
+\s*[0-9a-f]:\s*0000\s*bkpt\s*
+\s*[0-9a-f]:\s*00000000\s*\.long\s*0x00000000
+#...
diff --git a/gas/testsuite/gas/csky/jmpiv2_1.s b/gas/testsuite/gas/csky/jmpiv2_1.s
new file mode 100644
index 0000000..c7ad604
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpiv2_1.s
@@ -0,0 +1,6 @@
+.text
+
+LABEL:
+ bkpt
+ jmpi LABEL
+ bkpt
diff --git a/gas/testsuite/gas/csky/jmpiv2_2.d b/gas/testsuite/gas/csky/jmpiv2_2.d
new file mode 100644
index 0000000..c0aef4a
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpiv2_2.d
@@ -0,0 +1,9 @@
+# name: jmpiv2_2 - csky
+#as: -mcpu=ck810
+#readelf: -r --wide
+
+
+Relocation section '.rela.text\' at offset .* contains 1 entry:
+#...
+.*R_CKCORE_ADDR32[ \t]+00000000[ \t]+\.text \+[ \t]+[0-9a-f]+
+#pass
diff --git a/gas/testsuite/gas/csky/jmpiv2_2.s b/gas/testsuite/gas/csky/jmpiv2_2.s
new file mode 100644
index 0000000..c7ad604
--- /dev/null
+++ b/gas/testsuite/gas/csky/jmpiv2_2.s
@@ -0,0 +1,6 @@
+.text
+
+LABEL:
+ bkpt
+ jmpi LABEL
+ bkpt
diff --git a/gas/testsuite/gas/csky/jsriv2_1.d b/gas/testsuite/gas/csky/jsriv2_1.d
new file mode 100644
index 0000000..524f847
--- /dev/null
+++ b/gas/testsuite/gas/csky/jsriv2_1.d
@@ -0,0 +1,13 @@
+# name: jsriv2_1 - csky
+#as: -mcpu=ck807
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]:\s*0000\s*bkpt
+\s*[0-9a-f]:\s*eae00002\s*jsri\s*0x0\s*\/\/\s*from\s*address\s*pool\s*at\s*0x[0-9a-f]*
+\s*[0-9a-f]:\s*0000\s*.short\s*0x0000
+\s*[0-9a-f]:\s*00000000\s*.long\s*0x00000000
+#...
diff --git a/gas/testsuite/gas/csky/jsriv2_1.s b/gas/testsuite/gas/csky/jsriv2_1.s
new file mode 100644
index 0000000..45ce734
--- /dev/null
+++ b/gas/testsuite/gas/csky/jsriv2_1.s
@@ -0,0 +1,5 @@
+.text
+
+LABEL:
+bkpt
+jsri LABEL
diff --git a/gas/testsuite/gas/csky/jsriv2_2.d b/gas/testsuite/gas/csky/jsriv2_2.d
new file mode 100644
index 0000000..3a373b5
--- /dev/null
+++ b/gas/testsuite/gas/csky/jsriv2_2.d
@@ -0,0 +1,14 @@
+# name: jsriv2_2 - csky
+#as: -mcpu=ck810
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]:\s*0000\s*bkpt
+\s*[0-9a-f]:\s*e3ffffff\s*bsr\s*0x0\s*\/\/\s*0\s*<LABEL>
+\s*[0-9a-f]:\s*c4004820\s*lsli\s*r0,\s*\s*r0,\s*0
+\s*[0-9a-f]:\s*0000\s*.short\s*0x0000
+\s*[0-9a-f]:\s*00000000\s*.long\s*0x00000000
+#...
diff --git a/gas/testsuite/gas/csky/jsriv2_2.s b/gas/testsuite/gas/csky/jsriv2_2.s
new file mode 100644
index 0000000..45ce734
--- /dev/null
+++ b/gas/testsuite/gas/csky/jsriv2_2.s
@@ -0,0 +1,5 @@
+.text
+
+LABEL:
+bkpt
+jsri LABEL
diff --git a/gas/testsuite/gas/csky/jsriv2_3.d b/gas/testsuite/gas/csky/jsriv2_3.d
new file mode 100644
index 0000000..9e46368
--- /dev/null
+++ b/gas/testsuite/gas/csky/jsriv2_3.d
@@ -0,0 +1,9 @@
+# name: jsriv2_3 - csky
+#as: -mcpu=ck807
+#readelf: -r --wide
+
+
+Relocation section '.rela.text\' at offset .* contains 1 entry:
+#...
+00000008.*R_CKCORE_ADDR32[ \t]+00000000[ \t]+\.text \+[ \t]+[0-9a-f]+
+#pass
diff --git a/gas/testsuite/gas/csky/jsriv2_3.s b/gas/testsuite/gas/csky/jsriv2_3.s
new file mode 100644
index 0000000..45ce734
--- /dev/null
+++ b/gas/testsuite/gas/csky/jsriv2_3.s
@@ -0,0 +1,5 @@
+.text
+
+LABEL:
+bkpt
+jsri LABEL
diff --git a/gas/testsuite/gas/csky/jsriv2_4.d b/gas/testsuite/gas/csky/jsriv2_4.d
new file mode 100644
index 0000000..851ef6a
--- /dev/null
+++ b/gas/testsuite/gas/csky/jsriv2_4.d
@@ -0,0 +1,9 @@
+# name: jsriv2_4 - csky
+#as: -mcpu=ck810
+#readelf: -r --wide
+
+
+Relocation section '.rela.text\' at offset .* contains 1 entry:
+#...
+0000000c.*R_CKCORE_ADDR32[ \t]+00000000[ \t]+\.text \+[ \t]+[0-9a-f]+
+#pass
diff --git a/gas/testsuite/gas/csky/jsriv2_4.s b/gas/testsuite/gas/csky/jsriv2_4.s
new file mode 100644
index 0000000..45ce734
--- /dev/null
+++ b/gas/testsuite/gas/csky/jsriv2_4.s
@@ -0,0 +1,5 @@
+.text
+
+LABEL:
+bkpt
+jsri LABEL
diff --git a/gas/testsuite/gas/csky/trust.d b/gas/testsuite/gas/csky/trust.d
new file mode 100644
index 0000000..1a87b4d
--- /dev/null
+++ b/gas/testsuite/gas/csky/trust.d
@@ -0,0 +1,17 @@
+# name: trust - csky
+#as: -mcpu=ck810t
+#objdump: -d
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*c0003c20\s*wsc
+\s*[0-9a-f]*:\s*c0006024\s*mfcr\s*r4,\s*cr<0,\s*0>
+\s*[0-9a-f]*:\s*c0156024\s*mfcr\s*r4,\s*cr<21,\s*0>
+\s*[0-9a-f]*:\s*c004642b\s*mtcr\s*r4,\s*cr<11,\s*0>
+\s*[0-9a-f]*:\s*c0046428\s*mtcr\s*r4,\s*cr<8,\s*0>
+\s*[0-9a-f]*:\s*c0096024\s*mfcr\s*r4,\s*cr<9,\s*0>
+\s*[0-9a-f]*:\s*c2007420\s*psrset\s*sie
+\s*[0-9a-f]*:\s*c2007020\s*psrclr\s*sie
+#...
diff --git a/gas/testsuite/gas/csky/trust.s b/gas/testsuite/gas/csky/trust.s
new file mode 100644
index 0000000..781dc8cb
--- /dev/null
+++ b/gas/testsuite/gas/csky/trust.s
@@ -0,0 +1,9 @@
+TRUST:
+ wsc
+ mfcr r4, psr
+ mfcr r4, rid
+ mtcr r4, gcr
+ mtcr r4, sedcr
+ mfcr r4, sepcr
+ psrset sie
+ psrclr sie
diff --git a/gas/testsuite/gas/csky/v1_float.d b/gas/testsuite/gas/csky/v1_float.d
new file mode 100644
index 0000000..995a77d
--- /dev/null
+++ b/gas/testsuite/gas/csky/v1_float.d
@@ -0,0 +1,222 @@
+# name: csky - v1-float
+#as: -mcpu=ck610ef -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe06002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe06402.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffec1002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffec9002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffed9002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffee1002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffed1002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffee9002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffef1002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffef9002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+#...
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe04403.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe04c03.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe05403.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe05c03.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe38c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe48c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe58c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe68c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe78c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe88c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe98c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffea8c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffeb8c02.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe04002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe04802.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe05002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe05802.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe31002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe41002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe51002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe61002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe71002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe81002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe91002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffea1002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffeb1002.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+#...
+\s*[0-9a-f]*:\s*744a\s*lrw\s*r4,\s*0xffe00840.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7449\s*lrw\s*r4,\s*0xffe00c40.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7449\s*lrw\s*r4,\s*0xffe01040.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7448\s*lrw\s*r4,\s*0xffe01440.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7448\s*lrw\s*r4,\s*0xffe01841.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7447\s*lrw\s*r4,\s*0xffe01c41.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7447\s*lrw\s*r4,\s*0xffe02041.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7446\s*lrw\s*r4,\s*0xffe02441.*
+\s*[0-9a-f]*:\s*3204\s*cpwir\s*r4
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7346\s*lrw\s*r3,\s*0xffe00400.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7345\s*lrw\s*r3,\s*0xffe00480.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7345\s*lrw\s*r3,\s*0xffe00500.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7344\s*lrw\s*r3,\s*0xffe00580.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7344\s*lrw\s*r3,\s*0xffe00600.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7343\s*lrw\s*r3,\s*0xffe00680.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7343\s*lrw\s*r3,\s*0xffe00700.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*000d\s*cprc
+\s*[0-9a-f]*:\s*7342\s*lrw\s*r3,\s*0xffe00780.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*000d\s*cprc
+#...
+\s*[0-9a-f]*:\s*7242\s*lrw\s*r2,\s*0xffe02801.*
+\s*[0-9a-f]*:\s*3202\s*cpwir\s*r2
+\s*[0-9a-f]*:\s*7242\s*lrw\s*r2,\s*0xffe02c02.*
+\s*[0-9a-f]*:\s*3202\s*cpwir\s*r2
+\s*[0-9a-f]*:\s*7242\s*lrw\s*r2,\s*0xffe03402.*
+\s*[0-9a-f]*:\s*3202\s*cpwir\s*r2
+\s*[0-9a-f]*:\s*7242\s*lrw\s*r2,\s*0xffe03002.*
+\s*[0-9a-f]*:\s*3202\s*cpwir\s*r2
+\s*[0-9a-f]*:\s*7242\s*lrw\s*r2,\s*0xffe03c02.*
+\s*[0-9a-f]*:\s*3202\s*cpwir\s*r2
+\s*[0-9a-f]*:\s*7242\s*lrw\s*r2,\s*0xffe03802.*
+\s*[0-9a-f]*:\s*3202\s*cpwir\s*r2
+\s*[0-9a-f]*:\s*7342\s*lrw\s*r3,\s*0xffe10002.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*7342\s*lrw\s*r3,\s*0xffe08002.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*7342\s*lrw\s*r3,\s*0xffe20002.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+\s*[0-9a-f]*:\s*7342\s*lrw\s*r3,\s*0xffe18002.*
+\s*[0-9a-f]*:\s*3203\s*cpwir\s*r3
+#...
+\s*[0-9a-f]*:\s*2642\s*cpwgr\s*r2,\s*cpr4
+\s*[0-9a-f]*:\s*0842\s*cprgr\s*r2,\s*cpr4
+\s*[0-9a-f]*:\s*2642\s*cpwgr\s*r2,\s*cpr4
+\s*[0-9a-f]*:\s*2653\s*cpwgr\s*r3,\s*cpr5
+\s*[0-9a-f]*:\s*0842\s*cprgr\s*r2,\s*cpr4
+\s*[0-9a-f]*:\s*0853\s*cprgr\s*r3,\s*cpr5
+\s*[0-9a-f]*:\s*f7ff\s*br\s*0x124.*
+\s*[0-9a-f]*:\s*f7ff\s*br\s*0x126.*
+\s*[0-9a-f]*:\s*ffe06002\s*\.long\s*0xffe06002
+\s*[0-9a-f]*:\s*ffe06402\s*\.long\s*0xffe06402
+\s*[0-9a-f]*:\s*ffec1002\s*\.long\s*0xffec1002
+\s*[0-9a-f]*:\s*ffec9002\s*\.long\s*0xffec9002
+\s*[0-9a-f]*:\s*ffed9002\s*\.long\s*0xffed9002
+\s*[0-9a-f]*:\s*ffee1002\s*\.long\s*0xffee1002
+\s*[0-9a-f]*:\s*ffed1002\s*\.long\s*0xffed1002
+\s*[0-9a-f]*:\s*ffee9002\s*\.long\s*0xffee9002
+\s*[0-9a-f]*:\s*ffef1002\s*\.long\s*0xffef1002
+\s*[0-9a-f]*:\s*ffef9002\s*\.long\s*0xffef9002
+\s*[0-9a-f]*:\s*ffe04403\s*\.long\s*0xffe04403
+\s*[0-9a-f]*:\s*ffe04c03\s*\.long\s*0xffe04c03
+\s*[0-9a-f]*:\s*ffe05403\s*\.long\s*0xffe05403
+\s*[0-9a-f]*:\s*ffe05c03\s*\.long\s*0xffe05c03
+\s*[0-9a-f]*:\s*ffe38c02\s*\.long\s*0xffe38c02
+\s*[0-9a-f]*:\s*ffe48c02\s*\.long\s*0xffe48c02
+\s*[0-9a-f]*:\s*ffe58c02\s*\.long\s*0xffe58c02
+\s*[0-9a-f]*:\s*ffe68c02\s*\.long\s*0xffe68c02
+\s*[0-9a-f]*:\s*ffe78c02\s*\.long\s*0xffe78c02
+\s*[0-9a-f]*:\s*ffe88c02\s*\.long\s*0xffe88c02
+\s*[0-9a-f]*:\s*ffe98c02\s*\.long\s*0xffe98c02
+\s*[0-9a-f]*:\s*ffea8c02\s*\.long\s*0xffea8c02
+\s*[0-9a-f]*:\s*ffeb8c02\s*\.long\s*0xffeb8c02
+\s*[0-9a-f]*:\s*ffe04002\s*\.long\s*0xffe04002
+\s*[0-9a-f]*:\s*ffe04802\s*\.long\s*0xffe04802
+\s*[0-9a-f]*:\s*ffe05002\s*\.long\s*0xffe05002
+\s*[0-9a-f]*:\s*ffe05802\s*\.long\s*0xffe05802
+\s*[0-9a-f]*:\s*ffe31002\s*\.long\s*0xffe31002
+\s*[0-9a-f]*:\s*ffe41002\s*\.long\s*0xffe41002
+\s*[0-9a-f]*:\s*ffe51002\s*\.long\s*0xffe51002
+\s*[0-9a-f]*:\s*ffe61002\s*\.long\s*0xffe61002
+\s*[0-9a-f]*:\s*ffe71002\s*\.long\s*0xffe71002
+\s*[0-9a-f]*:\s*ffe81002\s*\.long\s*0xffe81002
+\s*[0-9a-f]*:\s*ffe91002\s*\.long\s*0xffe91002
+\s*[0-9a-f]*:\s*ffea1002\s*\.long\s*0xffea1002
+\s*[0-9a-f]*:\s*ffeb1002\s*\.long\s*0xffeb1002
+\s*[0-9a-f]*:\s*ffe00840\s*\.long\s*0xffe00840
+\s*[0-9a-f]*:\s*ffe00c40\s*\.long\s*0xffe00c40
+\s*[0-9a-f]*:\s*ffe01040\s*\.long\s*0xffe01040
+\s*[0-9a-f]*:\s*ffe01440\s*\.long\s*0xffe01440
+\s*[0-9a-f]*:\s*ffe01841\s*\.long\s*0xffe01841
+\s*[0-9a-f]*:\s*ffe01c41\s*\.long\s*0xffe01c41
+\s*[0-9a-f]*:\s*ffe02041\s*\.long\s*0xffe02041
+\s*[0-9a-f]*:\s*ffe02441\s*\.long\s*0xffe02441
+\s*[0-9a-f]*:\s*ffe00400\s*\.long\s*0xffe00400
+\s*[0-9a-f]*:\s*ffe00480\s*\.long\s*0xffe00480
+\s*[0-9a-f]*:\s*ffe00500\s*\.long\s*0xffe00500
+\s*[0-9a-f]*:\s*ffe00580\s*\.long\s*0xffe00580
+\s*[0-9a-f]*:\s*ffe00600\s*\.long\s*0xffe00600
+\s*[0-9a-f]*:\s*ffe00680\s*\.long\s*0xffe00680
+\s*[0-9a-f]*:\s*ffe00700\s*\.long\s*0xffe00700
+\s*[0-9a-f]*:\s*ffe00780\s*\.long\s*0xffe00780
+\s*[0-9a-f]*:\s*ffe02801\s*\.long\s*0xffe02801
+\s*[0-9a-f]*:\s*ffe02c02\s*\.long\s*0xffe02c02
+\s*[0-9a-f]*:\s*ffe03402\s*\.long\s*0xffe03402
+\s*[0-9a-f]*:\s*ffe03002\s*\.long\s*0xffe03002
+\s*[0-9a-f]*:\s*ffe03c02\s*\.long\s*0xffe03c02
+\s*[0-9a-f]*:\s*ffe03802\s*\.long\s*0xffe03802
+\s*[0-9a-f]*:\s*ffe10002\s*\.long\s*0xffe10002
+\s*[0-9a-f]*:\s*ffe08002\s*\.long\s*0xffe08002
+\s*[0-9a-f]*:\s*ffe20002\s*\.long\s*0xffe20002
+\s*[0-9a-f]*:\s*ffe18002\s*\.long\s*0xffe18002
diff --git a/gas/testsuite/gas/csky/v1_float.s b/gas/testsuite/gas/csky/v1_float.s
new file mode 100644
index 0000000..550379a
--- /dev/null
+++ b/gas/testsuite/gas/csky/v1_float.s
@@ -0,0 +1,78 @@
+.text
+
+L0:
+ fabsm fr0, fr2, r4
+ fnegm fr0, fr2, r4
+ faddm fr0, fr2, fr4, r4
+ fsubm fr0, fr2, fr4, r4
+ fmacm fr0, fr2, fr4, r4
+ fmscm fr0, fr2, fr4, r4
+ fmulm fr0, fr2, fr4, r4
+ fnmacm fr0, fr2, fr4, r4
+ fnmscm fr0, fr2, fr4, r4
+ fnmulm fr0, fr2, fr4, r4
+
+L1:
+ fabss fr0, fr3, r4
+ fnegs fr0, fr3, r4
+ fsqrts fr0, fr3, r4
+ frecips fr0, fr3, r4
+ fadds fr0, fr2, fr3, r4
+ fsubs fr0, fr2, fr3, r4
+ fmacs fr0, fr2, fr3, r4
+ fmscs fr0, fr2, fr3, r4
+ fmuls fr0, fr2, fr3, r4
+ fdivs fr0, fr2, fr3, r4
+ fnmacs fr0, fr2, fr3, r4
+ fnmscs fr0, fr2, fr3, r4
+ fnmuls fr0, fr2, fr3, r4
+
+ fabsd fr0, fr2, r4
+ fnegd fr0, fr2, r4
+ fsqrtd fr0, fr2, r4
+ frecipd fr0, fr2, r4
+ faddd fr0, fr2, fr4, r4
+ fsubd fr0, fr2, fr4, r4
+ fmacd fr0, fr2, fr4, r4
+ fmscd fr0, fr2, fr4, r4
+ fmuld fr0, fr2, fr4, r4
+ fdivd fr0, fr2, fr4, r4
+ fnmacd fr0, fr2, fr4, r4
+ fnmscd fr0, fr2, fr4, r4
+ fnmuld fr0, fr2, fr4, r4
+
+L2:
+ fcmphsd fr0, fr2, r4
+ fcmpltd fr0, fr2, r4
+ fcmpned fr0, fr2, r4
+ fcmpuod fr0, fr2, r4
+ fcmphss fr1, fr2, r4
+ fcmplts fr1, fr2, r4
+ fcmpnes fr1, fr2, r4
+ fcmpuos fr1, fr2, r4
+ fcmpzhsd fr0, r3
+ fcmpzltd fr0, r3
+ fcmpzned fr0, r3
+ fcmpzuod fr0, r3
+ fcmpzhss fr0, r3
+ fcmpzlts fr0, r3
+ fcmpznes fr0, r3
+ fcmpzuos fr0, r3
+
+L3:
+ fstod fr0, fr1, r2
+ fdtos fr0, fr2, r2
+ fsitos fr0, fr2, r2
+ fsitod fr0, fr2, r2
+ fuitos fr0, fr2, r2
+ fuitod fr0, fr2, r2
+ fstosi fr0, fr2, RM_NEAREST, r3
+ fdtosi fr0, fr2, RM_NEAREST, r3
+ fstoui fr0, fr2, RM_NEAREST, r3
+ fdtoui fr0, fr2, RM_NEAREST, r3
+
+L4:
+ fmts r2, fr4
+ fmfs r2, fr4
+ fmtd r2, fr4
+ fmfd r2, fr4
diff --git a/gas/testsuite/gas/csky/v2_float_part1.d b/gas/testsuite/gas/csky/v2_float_part1.d
new file mode 100644
index 0000000..aa0b0a4
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_float_part1.d
@@ -0,0 +1,54 @@
+# name: csky - v2-float
+#as: -mcpu=ck810ef -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*f4243403\s*fstms\s*fr3-fr4,\s*\(r4\)
+\s*[0-9a-f]*:\s*f4243003\s*fldms\s*fr3-fr4,\s*\(r4\)
+\s*[0-9a-f]*:\s*f4243603\s*fstmm\s*fr3-fr4,\s*\(r4\)
+\s*[0-9a-f]*:\s*f4243203\s*fldmm\s*fr3-fr4,\s*\(r4\)
+\s*[0-9a-f]*:\s*f4243503\s*fstmd\s*fr3-fr4,\s*\(r4\)
+\s*[0-9a-f]*:\s*f4243103\s*fldmd\s*fr3-fr4,\s*\(r4\)
+\s*[0-9a-f]*:\s*f4022600\s*fstm\s*fr0,\s*\(r2,\s*0x0\)
+\s*[0-9a-f]*:\s*f4022200\s*fldm\s*fr0,\s*\(r2,\s*0x0\)
+\s*[0-9a-f]*:\s*f4022610\s*fstm\s*fr0,\s*\(r2,\s*0x8\)
+\s*[0-9a-f]*:\s*f4022210\s*fldm\s*fr0,\s*\(r2,\s*0x8\)
+\s*[0-9a-f]*:\s*f4022510\s*fstd\s*fr0,\s*\(r2,\s*0x4\)
+\s*[0-9a-f]*:\s*f4022110\s*fldd\s*fr0,\s*\(r2,\s*0x4\)
+\s*[0-9a-f]*:\s*f4022410\s*fsts\s*fr0,\s*\(r2,\s*0x4\)
+\s*[0-9a-f]*:\s*f4022010\s*flds\s*fr0,\s*\(r2,\s*0x4\)
+\s*[0-9a-f]*:\s*f4822e02\s*fstrm\s*fr2,\s*\(r2,\s*r4\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f4822e42\s*fstrm\s*fr2,\s*\(r2,\s*r4\s*<<\s*2\)
+\s*[0-9a-f]*:\s*f4822d02\s*fstrd\s*fr2,\s*\(r2,\s*r4\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f4822d42\s*fstrd\s*fr2,\s*\(r2,\s*r4\s*<<\s*2\)
+\s*[0-9a-f]*:\s*f4822c02\s*fstrs\s*fr2,\s*\(r2,\s*r4\s*<<\s*0\)
+\s*[0-9a-f]*:\s*f4822c42\s*fstrs\s*fr2,\s*\(r2,\s*r4\s*<<\s*2\)
+\s*[0-9a-f]*:\s*f4831222\s*fnmulm\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f48312e2\s*fnmscm\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f48312c2\s*fnmacm\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f48312a2\s*fmscm\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4831282\s*fmacm\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4831202\s*fmulm\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4831022\s*fsubm\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4831002\s*faddm\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830a22\s*fnmuld\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830ae2\s*fnmscd\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830ac2\s*fnmacd\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830aa2\s*fmscd\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830a82\s*fmacd\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830b02\s*fdivd\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830a02\s*fmuld\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830822\s*fsubd\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830802\s*faddd\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830222\s*fnmuls\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f48302e2\s*fnmscs\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f48302c2\s*fnmacs\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f48302a2\s*fmscs\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830282\s*fmacs\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830302\s*fdivs\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830202\s*fmuls\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830022\s*fsubs\s*fr2,\s*fr3,\s*fr4
+\s*[0-9a-f]*:\s*f4830002\s*fadds\s*fr2,\s*fr3,\s*fr4
diff --git a/gas/testsuite/gas/csky/v2_float_part1.s b/gas/testsuite/gas/csky/v2_float_part1.s
new file mode 100644
index 0000000..826b32d
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_float_part1.s
@@ -0,0 +1,48 @@
+ .text
+L1:
+ fstms vr3-vr4, (r4)
+ fldms vr3-vr4, (r4)
+ fstmm vr3-vr4, (r4)
+ fldmm vr3-vr4, (r4)
+ fstmd vr3-vr4, (r4)
+ fldmd vr3-vr4, (r4)
+ fstm vr0, (r2, 0)
+ fldm vr0, (r2, 0)
+ fstm vr0, (r2, 8)
+ fldm vr0, (r2, 8)
+ fstd vr0, (r2, 4)
+ fldd vr0, (r2, 4)
+ fsts vr0, (r2, 4)
+ flds vr0, (r2, 4)
+ fstrm vr2, (r2, r4 << 0)
+ fstrm vr2, (r2, r4 << 2)
+ fstrd vr2, (r2, r4 << 0)
+ fstrd vr2, (r2, r4 << 2)
+ fstrs vr2, (r2, r4 << 0)
+ fstrs vr2, (r2, r4 << 2)
+ fnmulm vr2, vr3, vr4
+ fnmscm vr2, vr3, vr4
+ fnmacm vr2, vr3, vr4
+ fmscm vr2, vr3, vr4
+ fmacm vr2, vr3, vr4
+ fmulm vr2, vr3, vr4
+ fsubm vr2, vr3, vr4
+ faddm vr2, vr3, vr4
+ fnmuld vr2, vr3, vr4
+ fnmscd vr2, vr3, vr4
+ fnmacd vr2, vr3, vr4
+ fmscd vr2, vr3, vr4
+ fmacd vr2, vr3, vr4
+ fdivd vr2, vr3, vr4
+ fmuld vr2, vr3, vr4
+ fsubd vr2, vr3, vr4
+ faddd vr2, vr3, vr4
+ fnmuls vr2, vr3, vr4
+ fnmscs vr2, vr3, vr4
+ fnmacs vr2, vr3, vr4
+ fmscs vr2, vr3, vr4
+ fmacs vr2, vr3, vr4
+ fdivs vr2, vr3, vr4
+ fmuls vr2, vr3, vr4
+ fsubs vr2, vr3, vr4
+ fadds vr2, vr3, vr4
diff --git a/gas/testsuite/gas/csky/v2_float_part2.d b/gas/testsuite/gas/csky/v2_float_part2.d
new file mode 100644
index 0000000..94b04e0
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_float_part2.d
@@ -0,0 +1,20 @@
+# name: csky - v2-float-part2
+#as: -mcpu=ck807f -W
+#objdump: -D
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*f4003882\s*flrws\s*fr2,\s*3\.140000
+\s*[0-9a-f]*:\s*f50b1c02\s*fmovis\s*fr2,\s*1\.500000
+\s*[0-9a-f]*:\s*f51b1c02\s*fmovis\s*fr2,\s*-1\.500000
+\s*[0-9a-f]*:\s*f48a1c02\s*fmovis\s*fr2,\s*2\.500000
+#...
+\s*[0-9a-f]*:\s*f4003952\s*flrwd\s*fr2,\s*3\.140000
+\s*[0-9a-f]*:\s*f48a1e02\s*fmovid\s*fr2,\s*2\.500000
+\s*[0-9a-f]*:\s*f49a1e02\s*fmovid\s*fr2,\s*-2\.500000
+\s*[0-9a-f]*:\s*f51b1e02\s*fmovid\s*fr2,\s*-1\.500000
+\s*[0-9a-f]*:\s*4048f5c3\s*\.long\s*0x4048f5c3
+\s*[0-9a-f]*:\s*51eb851f\s*\.long\s*0x51eb851f
+\s*[0-9a-f]*:\s*40091eb8\s*\.long\s*0x40091eb8
diff --git a/gas/testsuite/gas/csky/v2_float_part2.s b/gas/testsuite/gas/csky/v2_float_part2.s
new file mode 100644
index 0000000..92c253b
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_float_part2.s
@@ -0,0 +1,10 @@
+only_in_803_807:
+ flrws fr2, 3.14
+ fmovis fr2, 1.5
+ fmovis fr2, -1.5
+ fmovis fr2, 2.5
+only_in_807:
+ flrwd fr2, 3.14
+ fmovid fr2, 2.5
+ fmovid fr2, -2.5
+ fmovid fr2, -1.5
diff --git a/gas/testsuite/gas/csky/v2_tls_gd.d b/gas/testsuite/gas/csky/v2_tls_gd.d
new file mode 100644
index 0000000..226beaa
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_tls_gd.d
@@ -0,0 +1,10 @@
+# name: csky - v2 TLS GD
+#as: -mcpu=ck810 -W
+#objdump: -Dr
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*R_CKCORE_TLS_GD32\s*xxx.*
+\s*[0-9a-f]*:\s*R_CKCORE_PLT32\s*__tls_get_addr
diff --git a/gas/testsuite/gas/csky/v2_tls_gd.s b/gas/testsuite/gas/csky/v2_tls_gd.s
new file mode 100644
index 0000000..4a419d3
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_tls_gd.s
@@ -0,0 +1,7 @@
+.LTLS0:
+ lrw a0, xxx@TLSGD32
+ grs a2, .LTLS0
+ addu a0, a0, a2
+ lrw a3, __tls_get_addr@PLT
+ ldr.w a3, (gb, a3 << 0)
+ jsr a3
diff --git a/gas/testsuite/gas/csky/v2_tls_ie.d b/gas/testsuite/gas/csky/v2_tls_ie.d
new file mode 100644
index 0000000..db77387
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_tls_ie.d
@@ -0,0 +1,9 @@
+# name: csky - v2 TLS IE
+#as: -mcpu=ck810 -W
+#objdump: -Dr
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*R_CKCORE_TLS_IE32\s*xxx.*
diff --git a/gas/testsuite/gas/csky/v2_tls_ie.s b/gas/testsuite/gas/csky/v2_tls_ie.s
new file mode 100644
index 0000000..15288c7
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_tls_ie.s
@@ -0,0 +1,7 @@
+.LTLS0:
+ lrw a3, xxx@GOTTPOFF
+ grs a2, .LTLS0
+ addu a3, a3, a2
+ ld.w a3, (a3, 0)
+ mov a2, tls
+ str.w a0, (a2, a3 << 0)
diff --git a/gas/testsuite/gas/csky/v2_tls_ld.d b/gas/testsuite/gas/csky/v2_tls_ld.d
new file mode 100644
index 0000000..9f12ace
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_tls_ld.d
@@ -0,0 +1,11 @@
+# name: csky - v2 TLS LD
+#as: -mcpu=ck810 -W
+#objdump: -Dr
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*R_CKCORE_TLS_LDM32\s*xxx.*
+\s*[0-9a-f]*:\s*R_CKCORE_PLT32\s*__tls_get_addr
+\s*[0-9a-f]*:\s*R_CKCORE_TLS_LDO32\s*xxx
diff --git a/gas/testsuite/gas/csky/v2_tls_ld.s b/gas/testsuite/gas/csky/v2_tls_ld.s
new file mode 100644
index 0000000..762f27e
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_tls_ld.s
@@ -0,0 +1,9 @@
+.LTLS0:
+ lrw a0, xxx@TLSLDM32
+ grs a2, .LTLS0
+ addu a0, a0, a2
+ lrw a3, __tls_get_addr@PLT
+ ldr.w a3, (gb, a3 << 0)
+ jsr a3
+ lrw a3, xxx@TLSLDO32
+ str.w l0, (a0, a3 << 0)
diff --git a/gas/testsuite/gas/csky/v2_tls_le.d b/gas/testsuite/gas/csky/v2_tls_le.d
new file mode 100644
index 0000000..c34d6d7
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_tls_le.d
@@ -0,0 +1,9 @@
+# name: csky - v2 TLS IE
+#as: -mcpu=ck810 -W
+#objdump: -Dr
+
+.*: +file format .*csky.*
+
+Disassembly of section \.text:
+#...
+\s*[0-9a-f]*:\s*R_CKCORE_TLS_LE32\s*xxx
diff --git a/gas/testsuite/gas/csky/v2_tls_le.s b/gas/testsuite/gas/csky/v2_tls_le.s
new file mode 100644
index 0000000..06b05f4
--- /dev/null
+++ b/gas/testsuite/gas/csky/v2_tls_le.s
@@ -0,0 +1,3 @@
+ lrw a3, xxx@TPOFF
+ mov a2, tls
+ str.w a0, (a2, a3 << 0)