public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] C-SKY: Add fpuv3 instructions and CK860 arch.
@ 2021-04-30 12:21 Geng Qi
  2021-05-24 10:49 ` Xianmiao Qu
  0 siblings, 1 reply; 5+ messages in thread
From: Geng Qi @ 2021-04-30 12:21 UTC (permalink / raw)
  To: gcc-patches, cooper.qu; +Cc: Geng Qi

gcc/ChangeLog:

	* config/csky/constraints.md ("W"): New constriant for mem operand
	with base reg, index register.
	("Q"): Renamed and modified "csky_valid_fpuv2_mem_operand" to
	"csky_valid_mem_constraint_operand" to deal with both "Q" and "W"
	constraint.
	("Dv"): New constraint for const double value that can be used at
	fmovi instruction.
	* config/csky/csky-modes.def (HFmode): New mode.
	* config/csky/csky-protos.h (csky_valid_fpuv2_mem_operand): Rename
	to "csky_valid_mem_constraint_operand" and new support for constraint
	"W".
	(csky_get_movedouble_length): New.
	(fpuv3_output_move): New.
	(fpuv3_const_double): New.
	* config/csky/csky.c (csky_option_override): New arch CK860 with fpv3.
	(decompose_csky_address): Robustness adjust.
	(csky_print_operand): New "CONST_DOUBLE" operand.
	(csky_output_move): New support for fpv3 instructions.
	(csky_get_movedouble_length): New.
	(fpuv3_output_move): New.
	(fpuv3_const_double): New.
	(csky_emit_compare): New cover for float comparsion.
	(csky_emit_compare_float): Refine.
	(csky_vaild_fpuv2_mem_operand): Rename to
	"csky_valid_mem_constraint_operand" and new support for constraint "W".
	(ck860_rtx_costs): New.
	(csky_rtx_costs): New subcall for CK860.
	(regno_reg_class): New vregs for fpuv3.
	(csky_dbx_regno): Likewise.
	(csky_cpu_cpp_builtins): New builtin macro for fpuv3.
	(csky_conditional_register_usage): New suporrot for fpuv3.
	(csky_dwarf_register_span): New suporrot for fpuv3.
	(csky_init_builtins, csky_mangle_type): New support for "__fp16" type.
	(ck810_legitimate_index_p): New support for fp16.
	* gcc/config/csky/csky.h (TARGET_TLS): ADD CK860.
	(CSKY_VREG_P, CSKY_VREG_LO_P, CSKY_VREG_HI_P): New support for fpuv3.
	(TARGET_SINGLE_FPU): New support for fpuv3.
	(TARGET_SUPPORT_FPV3): New macro.
	(FIRST_PSEUDO_REGISTER): Value change, since the new fpuv3 regs.
	(FIXED_REGISTERS, CALL_REALLY_USED_REGISTERS, REGISTER_NAMES,
	 REG_CLASS_CONTENTS): Support for fpuv3.
	* gcc/config/csky/csky.md (movsf): Move to cksy_insn_fpu.md and adjust.
	(csky_movsf_fpv2): Likewise.
	(ck801_movsf): Likewise.
	(csky_movsf): Likewise.
	(movdf): Likewise.
	(csky_movdf_fpv2): Likewise.
	(ck801_movdf): Likewise.
	(csky_movdf): Likewise.
	(movsicc): Refine. Use "comparison_operatior" instead of
	"ordered_comparison_operatior".
	(addsicc): Likewise.
	(CSKY_FIRST_VFP3_REGNUM, CSKY_LAST_VFP3_REGNUM): New constant.
	(call_value_internal_vh): New insn.
	* config/csky/csky_cores.def (CK860): New arch and cpu.
	(fpv3): New 4 fpus: fpv3_hf, fpv3_hsf, fpv3_sdf and fpv3.
	* config/csky/csky_insn_fpu.md (mov<float_mode>): Move the float mov
	patterns from csky.md here.
	(fpuv2 instructions): Refactor. Separate all float patterns into
	emit-patterns and match-patterns, remain the emit-patterns here, and
	move the match-patterns to csky_insn_fpuv2.md.
	(fpuv3 instructions): Add patterns and fuse part of them with the
	fpuv2's.
	* config/csky/csky_insn_fpuv2.md: New file for fpuv2 instructions.
	* config/csky/csky_insn_fpuv3.md: New flie and new patterns for fpuv3
	isntructions.
	* config/csky/csky_isa.def (fcr): New.
	(fpv3): New 4 isa sets: fpv3_hi, fpv3_hf, fpv3_sf and fpv3_df.
	(CK860): New definition for ck860.
	* gcc/config/csky/csky_tables.opt (ck860): New processors ck860,
	ck860f. And new arch ck860.
	(fpv3): New 4 fpus: fpv3_hf, fpv3_hsf, fpv3_sdf and fpv3.
	* config/csky/predicates.md (csky_float_comparsion_operator): Delete
	"geu", "gtu", "leu", "ltu", which will never appear at float comparison.
	* config/cksy/t-csky-elf, config/csky/t-csky-linux: New for ck860.
	* doc/md.texi: Add "Q" and "W" constraints for C-SKY.
---
 gcc/config/csky/constraints.md     |  13 +-
 gcc/config/csky/csky-modes.def     |   2 +
 gcc/config/csky/csky-protos.h      |   7 +-
 gcc/config/csky/csky.c             | 644 ++++++++++++++++++++++++++----
 gcc/config/csky/csky.h             | 162 ++++++--
 gcc/config/csky/csky.md            | 127 ++----
 gcc/config/csky/csky_cores.def     |  13 +
 gcc/config/csky/csky_insn_fpu.md   | 798 +++++++++++++++----------------------
 gcc/config/csky/csky_insn_fpuv2.md | 470 ++++++++++++++++++++++
 gcc/config/csky/csky_insn_fpuv3.md | 497 +++++++++++++++++++++++
 gcc/config/csky/csky_isa.def       |  15 +
 gcc/config/csky/csky_tables.opt    |  21 +
 gcc/config/csky/predicates.md      |   3 +-
 gcc/config/csky/t-csky-elf         |   9 +-
 gcc/config/csky/t-csky-linux       |  11 +-
 gcc/doc/md.texi                    |   8 +
 16 files changed, 2125 insertions(+), 675 deletions(-)
 create mode 100644 gcc/config/csky/csky-modes.def
 create mode 100644 gcc/config/csky/csky_insn_fpuv2.md
 create mode 100644 gcc/config/csky/csky_insn_fpuv3.md

diff --git a/gcc/config/csky/constraints.md b/gcc/config/csky/constraints.md
index 6067d3d..937cb81 100644
--- a/gcc/config/csky/constraints.md
+++ b/gcc/config/csky/constraints.md
@@ -34,7 +34,11 @@
 
 (define_memory_constraint "Q"
   "Memory operands with base register, index register and short displacement for FPUV2"
-  (match_test "csky_valid_fpuv2_mem_operand (op)"))
+  (match_test "csky_valid_mem_constraint_operand (op, \"Q\")"))
+
+(define_memory_constraint "W"
+  "Memory operands with base register, index register"
+  (match_test "csky_valid_mem_constraint_operand (op, \"W\")"))
 
 (define_constraint "R"
   "Memory operands whose address is a label_ref"
@@ -172,3 +176,10 @@
   "Constant in range [-8, -1]"
   (and (match_code "const_int")
        (match_test "CSKY_CONST_OK_FOR_US (ival)")))
+
+(define_constraint "Dv"
+ "@VFPv3
+  A const_double which can be used with a VFP fmovi
+  instruction."
+  (and (match_code "const_double")
+       (match_test "fpuv3_const_double_rtx (op)")))
diff --git a/gcc/config/csky/csky-modes.def b/gcc/config/csky/csky-modes.def
new file mode 100644
index 0000000..a2427ff
--- /dev/null
+++ b/gcc/config/csky/csky-modes.def
@@ -0,0 +1,2 @@
+/* Float modes.  */
+FLOAT_MODE (HF, 2, ieee_half_format);        /* Half-precision floating point */
diff --git a/gcc/config/csky/csky-protos.h b/gcc/config/csky/csky-protos.h
index 7a2e23e..7c6528b 100644
--- a/gcc/config/csky/csky-protos.h
+++ b/gcc/config/csky/csky-protos.h
@@ -30,7 +30,7 @@ extern void csky_cpu_cpp_builtins (cpp_reader *);
 extern bool csky_inlinable_constant (HOST_WIDE_INT value);
 extern bool csky_shifted_imm8_constant (unsigned HOST_WIDE_INT,
 					unsigned int *, unsigned int *);
-extern bool csky_valid_fpuv2_mem_operand (rtx);
+extern bool csky_valid_mem_constraint_operand (rtx, const char*);
 
 extern bool csky_minipool_load_p (rtx_insn *);
 extern const char *csky_output_move (rtx insn, rtx *, machine_mode);
@@ -70,4 +70,9 @@ extern int csky_default_branch_cost (bool, bool);
 extern bool csky_default_logical_op_non_short_circuit (void);
 
 extern void csky_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+extern int csky_get_movedouble_length(rtx operands[]);
+
+/* The functions was used for fpuv3.  */
+extern const char *fpuv3_output_move (rtx *operands);
+extern int fpuv3_const_double_rtx (rtx);
 #endif /* GCC_CSKY_PROTOS_H */
diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
index cdb95fe..6e97994 100644
--- a/gcc/config/csky/csky.c
+++ b/gcc/config/csky/csky.c
@@ -126,7 +126,46 @@ enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER] =
   /* Reserved.  */
   RESERVE_REGS, RESERVE_REGS,
   /* Register epc.  */
-  OTHER_REGS
+  OTHER_REGS,
+  /* Vec registers.  */
+  V_REGS,       V_REGS,       V_REGS,       V_REGS,
+  V_REGS,       V_REGS,       V_REGS,       V_REGS,
+  V_REGS,       V_REGS,       V_REGS,       V_REGS,
+  V_REGS,       V_REGS,       V_REGS,       V_REGS,
+  /* Reserved.  */
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  /* Reserved.  */
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
+
+  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS
 };
 
 /* Arrays that map GCC register numbers to debugger register numbers,
@@ -138,11 +177,34 @@ const int csky_dbx_regno[FIRST_PSEUDO_REGISTER] =
   8,  9,  10, 11, 12, 13, 14, 15,
   16, 17, 18, 19, 20, 21, 22, 23,
   24, 25, 26, 27, 28, 29, 30, 31,
-  -1, -1, 36, 37, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, 56, 57, 58, 59,
-  60, 61, 62, 63, 64, 65, 66, 67,
-  68, 69, 70, 71, -1, -1, 72
+  -1, -1, 36, 37,
+  75,  79,  83,  87,  91,  95,  99,  103,
+  107, 111, 115, 119, 123, 127, 131, 135,
+  74,  78,  82,  86,  90,  94,  98,  102,
+  106, 110, 114, 118, 122, 126, 130, 134,
+  -1, -1, 72,
+  /* vr: 71 - 86 */
+  139,  143,  147,  151,  155,  159,  163,  167,
+  171,  175,  179,  183,  187,  191,  195,  199,
+  138,  142,  146,  150,  154,  158,  162,  166,
+  170,  174,  178,  182,  186,  190,  194,  198,
+  /* resereved */
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
+
+  -1,   -1,   -1
 };
 
 /* Table of machine attributes.  */
@@ -351,6 +413,12 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
       builtin_define ("__CSKY_FPUV2__");
     }
 
+  if (TARGET_SUPPORT_FPV3)
+    {
+      builtin_define ("__csky_fpuv3__");
+      builtin_define ("__CSKY_FPUV3__");
+    }
+
   if (TARGET_ELRW)
     {
       builtin_define ("__csky_elrw__");
@@ -408,7 +476,6 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
  *			   Storage Layout			  *
  ******************************************************************/
 
-
 #undef	TARGET_PROMOTE_FUNCTION_MODE
 #define TARGET_PROMOTE_FUNCTION_MODE \
   default_promote_function_mode_always_promote
@@ -416,6 +483,9 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
 #undef TARGET_CONSTANT_ALIGNMENT
 #define TARGET_CONSTANT_ALIGNMENT csky_constant_alignment
 
+#undef TARGET_MANGLE_TYPE
+#define TARGET_MANGLE_TYPE csky_mangle_type
+
 
 /******************************************************************
  *		Stack Layout and Calling Conventions		  *
@@ -692,6 +762,15 @@ csky_default_logical_op_non_short_circuit (void)
 #define	 TARGET_SCHED_ADJUST_COST csky_sched_adjust_cost
 
 
+/******************************************************************
+ *			Builtin					  *
+ ******************************************************************/
+
+
+#undef  TARGET_INIT_BUILTINS
+#define TARGET_INIT_BUILTINS  csky_init_builtins
+
+
 /* The declaration of functions.  */
 static void push_csky_minipool_fix (rtx_insn *, HOST_WIDE_INT, rtx *,
 				    machine_mode, rtx);
@@ -837,6 +916,7 @@ Mfix *minipool_fix_tail;
 Mfix *minipool_barrier;
 
 /* Allow GC scanning of the minipool obstack.  */
+
 static void
 csky_add_gc_roots (void)
 {
@@ -846,6 +926,7 @@ csky_add_gc_roots (void)
 
 /* Implement TARGET_CONSTANT_ALIGNMENT.
    Make strings word-aligned so strcpy from constants will be faster.  */
+
 static HOST_WIDE_INT
 csky_constant_alignment (const_tree exp, HOST_WIDE_INT align)
 {
@@ -1109,6 +1190,7 @@ get_csky_barrier_cost (rtx_insn *insn)
    (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
    Create the barrier by inserting a jump and add a new fix entry for
    it.  */
+
 static Mfix *
 create_csky_fix_barrier (Mfix *fix, Mfix *fix_next,
 			 HOST_WIDE_INT max_address)
@@ -1455,6 +1537,7 @@ csky_compute_pushpop_length (rtx *operands)
 }
 
 /* Emit constant pools for -mconstpool.  */
+
 static void
 csky_emit_constant_pools (void)
 {
@@ -1796,6 +1879,7 @@ csky_initial_elimination_offset (int from, int to)
    CUM is a variable of type CUMULATIVE_ARGS which gives info about
     the preceding args and about the function being called.
    ARG is a description of the argument.  */
+
 static rtx
 csky_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
 {
@@ -1921,6 +2005,7 @@ csky_function_value (const_tree type, const_tree func,
 
 
 /* Implement TARGET_LIBCALL_VALUE.  */
+
 static rtx
 csky_libcall_value (machine_mode mode,
 		    const_rtx libcall ATTRIBUTE_UNUSED)
@@ -1949,6 +2034,7 @@ csky_function_value_regno_p (const unsigned int regno)
 
 /* Return an RTX indicating where the return address to the
    calling function can be found.  */
+
 rtx
 csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
 {
@@ -1964,6 +2050,7 @@ csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
    that must be put in registers. The value must be zero for arguments
    that are passed entirely in registers or
    that are entirely pushed on the stack.  */
+
 static int
 csky_arg_partial_bytes (cumulative_args_t pcum_v, const function_arg_info &arg)
 {
@@ -2180,7 +2267,19 @@ csky_conditional_register_usage (void)
       int regno;
 
       for (regno = CSKY_FIRST_VFP_REGNUM;
-	   regno <= CSKY_LAST_VFP_REGNUM; regno++)
+	   regno <= CSKY_LAST_VFP3_REGNUM; regno++)
+	{
+	  fixed_regs[regno] = 1;
+	  call_used_regs[regno] = 1;
+	}
+    }
+
+  if (!TARGET_SUPPORT_FPV3)
+    {
+      int regno;
+
+      for (regno = CSKY_FIRST_VFP3_REGNUM;
+	   regno <= CSKY_LAST_VFP3_REGNUM; regno++)
 	{
 	  fixed_regs[regno] = 1;
 	  call_used_regs[regno] = 1;
@@ -2198,6 +2297,7 @@ csky_conditional_register_usage (void)
 }
 
 /* Implement TARGET_HARD_REGNO_NREGS.  */
+
 static unsigned int
 csky_hard_regno_nregs (unsigned int regno, machine_mode mode)
 {
@@ -2261,6 +2361,7 @@ csky_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
 /* Implement TARGET_MODES_TIEABLE_P.  We can't tie DFmode with other modes
    when V_REGs might be in use because those registers mess with the stored
    bits.  */
+
 static bool
 csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 {
@@ -2272,6 +2373,7 @@ csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 /* Implement TARGET_CAN_CHANGE_MODE_CLASS.
    V_REG registers can't do subreg as all values are reformatted to
    internal precision.  */
+
 static bool
 csky_can_change_mode_class (machine_mode from,
 			    machine_mode to,
@@ -2406,6 +2508,7 @@ csky_spill_class (reg_class_t rclass, machine_mode mode ATTRIBUTE_UNUSED)
 
 /* Convert a static initializer array of feature bits to sbitmap
    representation.  */
+
 static void
 csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
 {
@@ -2417,6 +2520,7 @@ csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
 
 /* Configure a build target TARGET from the user-specified options OPTS and
    OPTS_SET.  */
+
 static void
 csky_configure_build_target (struct csky_build_target *target,
 			     struct cl_target_option *opts,
@@ -2508,7 +2612,9 @@ csky_option_override (void)
 
   csky_base_arch = csky_active_target.base_arch;
 
-  if (flag_pic && !(CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK807)))
+  if (flag_pic && !(CSKY_TARGET_ARCH (CK807)
+		   || CSKY_TARGET_ARCH (CK810)
+		   || CSKY_TARGET_ARCH (CK860)))
     {
       flag_pic = 0;
       warning (0, "%qs is not supported by arch %s",
@@ -2526,19 +2632,21 @@ csky_option_override (void)
 	  bool ok;
 	  int fpu_index;
 
-#ifdef CSKY_FPUTYPE_DEFAULT
-	  target_fpu_name = CSKY_FPUTYPE_DEFAULT;
-#else
-	  target_fpu_name = "fpv2";
-#endif
-
 	  if (csky_active_target.core_name != NULL
 	      && !strchr (csky_active_target.core_name, 'f'))
 	    target_fpu_name = "auto";
 	  else if (CSKY_TARGET_ARCH (CK803) || !TARGET_DOUBLE_FLOAT)
 	    target_fpu_name = "fpv2_sf";
+	  else if (CSKY_TARGET_ARCH (CK860))
+	    target_fpu_name = "fpv3";
 	  else if (TARGET_DOUBLE_FLOAT && TARGET_FDIVDU)
 	    target_fpu_name = "fpv2_divd";
+	  else
+#ifdef CSKY_FPUTYPE_DEFAULT
+	    target_fpu_name = CSKY_FPUTYPE_DEFAULT;
+#else
+	    target_fpu_name = "fpv2";
+#endif
 
 	  ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &fpu_index,
 				      CL_TARGET);
@@ -3020,10 +3128,8 @@ ck810_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
 {
   enum rtx_code code = GET_CODE (index);
 
-  if (TARGET_HARD_FLOAT
-      && (mode == SFmode || mode == DFmode))
-    return (code == CONST_INT && INTVAL (index) < 1024
-	    && INTVAL (index) >= 0
+  if (code == CONST_INT && TARGET_HARD_FLOAT && CSKY_VREG_MODE_P (mode))
+    return (INTVAL (index) < 1024 && INTVAL (index) >= 0
 	    && (INTVAL (index) & 3) == 0);
 
   if (code == CONST_INT)
@@ -3183,7 +3289,7 @@ static bool
 decompose_csky_address (rtx addr, struct csky_address *out)
 {
   rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
-  HOST_WIDE_INT scale = 1;
+  HOST_WIDE_INT scale = 0;
   rtx scale_rtx = NULL_RTX;
   int i;
 
@@ -3231,7 +3337,10 @@ decompose_csky_address (rtx addr, struct csky_address *out)
 	      if (!base)
 		base = op;
 	      else if (!index)
-		index = op;
+		{
+		  index = op;
+		  scale = 1;
+		}
 	      else
 		return false;
 	      break;
@@ -3259,7 +3368,7 @@ decompose_csky_address (rtx addr, struct csky_address *out)
 	      scale_rtx = XEXP (op, 1);
 	      if (!CONST_INT_P (scale_rtx))
 		return false;
-	      scale = scale << INTVAL (scale_rtx);
+	      scale = 1 << INTVAL (scale_rtx);
 	      break;
 	    default:
 	      return false;
@@ -3484,6 +3593,14 @@ csky_print_operand (FILE *stream, rtx x, int code)
 	case UNSPEC:
 	  csky_output_pic_addr_const (stream, x, code);
 	  break;
+	case CONST_DOUBLE:
+	  {
+	    char fpstr[20];
+	    real_to_decimal ( fpstr, CONST_DOUBLE_REAL_VALUE (x),
+			     sizeof (fpstr), 0, 1);
+	    fprintf (stream, "%s", fpstr);
+	  }
+	  break;
 	default:
 	  output_addr_const (stream, x);
 	  break;
@@ -3997,17 +4114,37 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 		return "mfhi\t%0";
 	    }
 
-	    if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
-	      return "fmovs\t%0, %1";
-	    if (CSKY_VREG_P (dstreg))
-	      return "fmtvrl\t%0, %1";
-	    if (CSKY_VREG_P (srcreg))
-	      return "fmfvrl\t%0, %1";
-
-	    if (REGNO (src) == CSKY_CC_REGNUM)
-	      return "mvc\t%0";
-	    else
-	      return "mov\t%0, %1";
+	  if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
+	    {
+	      if (CSKY_ISA_FEATURE (fpv2_sf))
+		return "fmovs\t%0, %1";
+	      else if (CSKY_ISA_FEATURE (fpv3_sf))
+		return "fmov.32\t%0, %1";
+	      else
+		gcc_unreachable ();
+	    }
+	  if (CSKY_VREG_P (dstreg))
+	    {
+	      if (CSKY_ISA_FEATURE (fpv2_sf))
+		return "fmtvrl\t%0, %1";
+	      else if (CSKY_ISA_FEATURE (fpv3_sf))
+		return "fmtvr.32.1\t%0, %1";
+	      else
+		gcc_unreachable ();
+	    }
+	  if (CSKY_VREG_P (srcreg))
+	    {
+	      if (CSKY_ISA_FEATURE (fpv2_sf))
+		return "fmfvrl\t%0, %1";
+	      else if (CSKY_ISA_FEATURE (fpv3_sf))
+		return "fmfvr.32.1\t%0, %1";
+	      else
+		gcc_unreachable ();
+	    }
+	  if (REGNO (src) == CSKY_CC_REGNUM)
+	    return "mvc\t%0";
+	  else
+	    return "mov\t%0, %1";
 	}
       /* The situation mov memory to reg.  */
       else if (GET_CODE (src) == MEM)
@@ -4018,13 +4155,21 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	    switch (GET_MODE (src))
 	      {
 	      case E_HImode:
+	      case E_HFmode:
 		return "ldr.h\t%0, %1";
 	      case E_QImode:
 		return "ldr.b\t%0, %1";
 	      case E_SImode:
 	      case E_SFmode:
 		if (CSKY_VREG_P (REGNO (dst)))
-		  return "fldrs\t%0, %1";
+		  {
+		    if (CSKY_ISA_FEATURE(fpv2_sf))
+		      return "fldrs\t%0, %1";
+		    else if (CSKY_ISA_FEATURE(fpv3_sf))
+		      return "fldr.32\t%0, %1";
+		    else
+		      gcc_unreachable ();
+		    }
 		else
 		  return "ldr.w\t%0, %1";
 	      default:
@@ -4042,13 +4187,21 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	    switch (GET_MODE (src))
 	      {
 	      case E_HImode:
+	      case E_HFmode:
 		return "ld.h\t%0, %1";
 	      case E_QImode:
 		return "ld.b\t%0, %1";
 	      case E_SFmode:
 	      case E_SImode:
 		if (CSKY_VREG_P (REGNO (dst)))
-		  return "flds\t%0, %1";
+		  {
+		     if (CSKY_ISA_FEATURE(fpv2_sf))
+		       return "flds\t%0, %1";
+		     else if (CSKY_ISA_FEATURE(fpv3_sf))
+		       return "fld.32\t%0, %1";
+		     else
+		       gcc_unreachable ();
+		   }
 		else
 		  return "ld.w\t%0, %1";
 	      default:
@@ -4106,7 +4259,14 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	  case E_SFmode:
 	  case E_SImode:
 	    if (CSKY_VREG_P (REGNO (src)))
-	      return "fstrs\t%1, %0";
+	      {
+		if (CSKY_ISA_FEATURE(fpv2_sf))
+		  return "fstrs\t%1, %0";
+		else if (CSKY_ISA_FEATURE(fpv3_sf))
+		  return "fstr.32\t%1, %0";
+		else
+		  gcc_unreachable ();
+	      }
 	    else
 	      return "str.w\t%1, %0";
 	  default:
@@ -4122,7 +4282,14 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	  case E_SImode:
 	  case E_SFmode:
 	    if (CSKY_VREG_P (REGNO (src)))
-	      return "fsts\t%1, %0";
+	      {
+		if (CSKY_ISA_FEATURE(fpv2_sf))
+		  return "fsts\t%1, %0";
+		else if (CSKY_ISA_FEATURE(fpv3_sf))
+		  return "fst.32\t%1, %0";
+		else
+		  gcc_unreachable ();
+	      }
 	    else
 	      return "st.w\t%1, %0";
 	  default:
@@ -4261,7 +4428,14 @@ csky_output_movedouble (rtx operands[],
 		return "mthi\t%R1\n\tmtlo\t%1";
 	    }
 	  else if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
-	    return "fmovd\t%0, %1";
+	    {
+	      if (CSKY_ISA_FEATURE(fpv2_df))
+		return "fmovd\t%0, %1";
+	      else if (CSKY_ISA_FEATURE(fpv3_df))
+		return "fmov.64\t%0, %1";
+	      else
+		gcc_unreachable ();
+	    }
 	  else if (CSKY_VREG_P (srcreg))
 	    {
 	      /* Since the vector registers in fpuv2_soft processors
@@ -4270,18 +4444,46 @@ csky_output_movedouble (rtx operands[],
 	      if (TARGET_SOFT_FPU)
 		  return "fmfvrl\t%0, %1";
 	      else if (TARGET_BIG_ENDIAN)
-		return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fmfvr.64\t%R0, %0, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	      else
-		return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fmfvr.64\t%0, %R0, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	    }
 	  else if (CSKY_VREG_P (dstreg))
 	    {
 	      if (TARGET_SOFT_FPU)
 		return "fmtvrl\t%0, %1";
 	      else if (TARGET_BIG_ENDIAN)
-		return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fmtvr.64\t%0, %R1, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	      else
-		return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fmtvr.64\t%0, %1, %R1";
+		  else
+		    gcc_unreachable ();
+		}
 	    }
 
 	  /* Ensure the second source not overwritten.  */
@@ -4323,9 +4525,23 @@ csky_output_movedouble (rtx operands[],
 	  if (CSKY_VREG_P (dstreg))
 	    {
 	      if (op0.index)
-		return "fldrd\t%0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fldrd\t%0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fldr.64\t%0, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	      else
-		return "fldd\t%0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fldd\t%0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fld.64\t%0, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	    }
 	  /* FIXME length attribute is wrong here.  */
 	  if (dstreg == basereg)
@@ -4389,9 +4605,23 @@ csky_output_movedouble (rtx operands[],
       if (CSKY_VREG_P (srcreg))
 	{
 	  if (op0.index)
-	    return "fstrd\t%1, %0";
+	    {
+	      if (CSKY_ISA_FEATURE(fpv2_df))
+		return "fstrd\t%1, %0";
+	      else if (CSKY_ISA_FEATURE(fpv3_df))
+		return "fstr.64\t%1, %0";
+	      else
+		gcc_unreachable ();
+	    }
 	  else
-	    return "fstd\t%1, %0";
+	    {
+	      if (CSKY_ISA_FEATURE(fpv2_df))
+		return "fstd\t%1, %0";
+	      else if (CSKY_ISA_FEATURE(fpv3_df))
+		return "fst.64\t%1, %0";
+	      else
+		gcc_unreachable ();
+	    }
 	}
       /* FIXME length attribute is wrong here.  */
       if (srcreg == basereg)
@@ -4518,9 +4748,181 @@ csky_output_ck801_movedouble (rtx operands[],
     gcc_unreachable ();
 }
 
+/* Calculate the instruction's length for moving double-word data.  */
+
+int
+csky_get_movedouble_length(rtx operands[])
+{
+  rtx dst = operands[0];
+  rtx src = operands[1];
+
+  if (REG_P (dst))
+    {
+      if (REG_P (src))
+	{
+	  int dstreg = REGNO (dst);
+	  int srcreg = REGNO (src);
+
+	  if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
+	    return 4;
+	  else
+	    return 8;
+	}
+      else if (GET_CODE (src) == MEM)
+	{
+	  rtx memexp = XEXP (src, 0);
+	  int dstreg = REGNO (dst);
+	  struct csky_address op0;
+	  decompose_csky_address (XEXP (src, 0), &op0);
+
+	  if (GET_CODE (memexp) == LABEL_REF)
+	    return 8;
+	  if (CSKY_VREG_P (dstreg))
+	    return 4;
+	  return 8;
+	}
+      else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
+	{
+	  split_double (src, operands + 2, operands + 3);
+	  if (CSKY_CONST_OK_FOR_N (INTVAL (operands[2]) + 1)
+	      && CSKY_CONST_OK_FOR_N (INTVAL (operands[3]) + 1)
+	      && REGNO (operands[0]) < 6)
+	    return 4;
+	  else
+	    return 8;
+	}
+    }
+  else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
+    {
+      rtx memexp = XEXP (dst, 0);
+      int srcreg = REGNO (src);
+      int offset = -1;
+      if (CSKY_VREG_P (srcreg))
+	return 4;
+
+      if (GET_CODE (memexp) == REG)
+	offset = 0;
+      else if (GET_CODE (memexp) == PLUS)
+	{
+	  if (GET_CODE (XEXP (memexp, 0)) == REG)
+	    offset = INTVAL (XEXP (memexp, 1));
+	  else if (GET_CODE (XEXP (memexp, 1)) == REG)
+	    offset = INTVAL (XEXP (memexp, 0));
+	  else
+	    gcc_unreachable ();
+	}
+      else
+	gcc_unreachable ();
+
+      if (srcreg <= 6 && offset <= 1020)
+	return 4;
+      else if ((srcreg == 7 && offset <= 1024) || (srcreg <= 7 && offset == 1024))
+	return 6;
+      else
+	return 8;
+    }
+  else
+    gcc_unreachable ();
+
+  return 0;
+}
+
+/* Output float point load/store instructions for fpuv3.  */
+
+const char *
+fpuv3_output_move (rtx *operands)
+{
+  rtx reg, mem, addr, ops[2];
+  bool isload = REG_P (operands[0]);
+
+  const char *templ = "f%s%s.%s\t%%0, %%1";
+  char buff[50];
+  machine_mode mode;
+
+  reg = operands[isload ? 0 : 1];
+  mem = operands[isload ? 1 : 0];
+
+  gcc_assert (REG_P (reg));
+  gcc_assert (CSKY_VREG_P (REGNO (reg)));
+  gcc_assert (MEM_P (mem));
+
+  mode = GET_MODE (reg);
+  const char *type = mode == DFmode ? "64" :
+		     mode == SFmode ? "32" :
+		     mode == HFmode ? "16" :
+		     NULL;
+  gcc_assert(type != NULL);
+
+  addr = XEXP (mem, 0);
+  struct csky_address caddr;
+  decompose_csky_address (addr, &caddr);
+
+  ops[0] = reg;
+  ops[1] = mem;
+  sprintf (buff, templ,
+	   isload ? "ld" : "st",
+	   caddr.index ? "r" : "",
+	   type);
+  output_asm_insn (buff, ops);
+
+  return "";
+}
+
+/* Check if a const_double can be used by a VFP fmovi instruction.  */
+
+int
+fpuv3_const_double_rtx (rtx x)
+{
+  REAL_VALUE_TYPE r, m;
+  r = *CONST_DOUBLE_REAL_VALUE (x);
+
+  /* Fpuv3 doesn't support the following values.  */
+  if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r) || REAL_VALUE_MINUS_ZERO (r)
+      || r.cl == rvc_zero)
+    return 0;
+
+  /* Extract sign, exponent and mantissa.  */
+  int exponent;
+  r = real_value_abs (&r);
+  exponent = REAL_EXP (&r);
+
+  bool fail;
+  unsigned HOST_WIDE_INT mantissa, mant_hi;
+  unsigned HOST_WIDE_INT mask;
+  int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1;
+  real_ldexp (&m, &r, point_pos - exponent);
+  wide_int w = real_to_integer (&m, &fail, HOST_BITS_PER_WIDE_INT * 2);
+  mantissa = w.elt (0);
+  mant_hi = w.elt (1);
+
+  exponent -= 1;
+
+  if (!IN_RANGE (exponent, -4, 11))
+    return 0;
+
+  /* If there are bits set in the low part of the mantissa, these values are
+     not supported.  */
+  if (mantissa != 0)
+    return 0;
+
+  /* Now, make the mantissa contain the most-significant bits, and the
+     point_pos indicates the number of these bits.  */
+  point_pos -= HOST_BITS_PER_WIDE_INT;
+  mantissa = mant_hi;
+
+  /* We can only allow a mantissa of 9 significant digits, top of which is always 1.  */
+  mask = ((unsigned HOST_WIDE_INT)1 << (point_pos - 9)) - 1;
+  if ((mantissa & mask) != 0)
+    return 0;
+
+  return 1;
+}
+
+
 /* Split operands for an AND expression when OPERANDS[2] is a constant.
    Note operands[0] is marked earlyclobber in this case and can be
    overwritten.  Return true if "DONE", false otherwise.  */
+
 bool
 csky_split_and (rtx *operands)
 {
@@ -4650,6 +5052,7 @@ csky_split_and (rtx *operands)
 /* Split operands for an IOR expression when OPERANDS[2] is a constant.
    Note operands[0] is marked earlyclobber in this case and can be
    overwritten.  Return true if "DONE", false otherwise.  */
+
 bool
 csky_split_ior (rtx *operands)
 {
@@ -4717,6 +5120,7 @@ csky_split_ior (rtx *operands)
 /* Split operands for an XOR expression when OPERANDS[2] is a constant.
    Note operands[0] is marked earlyclobber in this case and can be
    overwritten.  Return true if "DONE", false otherwise.  */
+
 bool
 csky_split_xor (rtx *operands)
 {
@@ -4765,6 +5169,7 @@ csky_split_xor (rtx *operands)
 
 
 /* Return true if X is an address form involving a symbol or label ref.  */
+
 bool
 csky_symbolic_address_p (rtx x)
 {
@@ -4793,6 +5198,9 @@ csky_emit_compare (enum rtx_code code, rtx op0, rtx op1)
   bool invert;
   rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
 
+  if (GET_MODE_CLASS(GET_MODE (op0)) == MODE_FLOAT)
+    return csky_emit_compare_float(code, op0, op1);
+
   if (GET_CODE (op1) == CONST_INT)
     {
       HOST_WIDE_INT val = INTVAL (op1);
@@ -5707,6 +6115,7 @@ tls_unspec_mentioned_p (rtx x)
 
 
 /* Implement LEGITIMATE_PIC_OPERAND_P.  */
+
 bool
 csky_legitimate_pic_operand_p (rtx x)
 {
@@ -5938,33 +6347,20 @@ csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
     op1 = force_reg (mode, op1);
 
   invert = false;
+
   switch (code)
     {
     case EQ:
       code = NE;
       invert = true;
       break;
-
-    case NE:
-      break;
-    case LE:
-      if (op1 == CONST0_RTX (mode))
-	op1 = force_reg (mode, op1);
-      break;
     case GT:
-      if (op1 == CONST0_RTX (mode))
-	op1 = force_reg (mode, op1);
-      break;
-    case GE:
-      break;
     case LT:
-      if (op1 == CONST0_RTX (mode))
-	{
-	  code = GE;
-	  invert = true;
-	}
-      break;
-    case UNORDERED:
+    case LE:
+      if (op1 == CONST0_RTX (mode) && (CSKY_ISA_FEATURE_GET(fpv2_sf)
+				       || CSKY_ISA_FEATURE_GET(fpv2_df)
+				       || CSKY_ISA_FEATURE_GET(fpv2_divd)))
+	op1 = force_reg (mode, op1);
       break;
     case ORDERED:
       code = UNORDERED;
@@ -5980,10 +6376,11 @@ csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
   return invert;
 }
 
-/* Support for the Q memory constraint.  Returns true if OP is a MEM RTX
-   with an address consisting of base + index or base + displacement.  */
+/* Support for the Q or W memory constraint.  Returns true if OP is a MEM
+   RTX with an address consisting of base + index or base + displacement.  */
+
 bool
-csky_valid_fpuv2_mem_operand (rtx op)
+csky_valid_mem_constraint_operand (rtx op, const char *constraint)
 {
   struct csky_address addr;
 
@@ -5998,7 +6395,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
     return false;
 
   /* Verify index operand. */
-  if (addr.index)
+  if (addr.index && (constraint[0] == 'Q' || constraint[0] == 'W'))
     {
       if (!is_csky_address_register_rtx_p (addr.index, 0))
 	return false;
@@ -6010,7 +6407,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
       return false;
     }
   /* Verify disp operand.  */
-  else if (addr.disp)
+  else if (addr.disp && constraint[0] == 'Q')
     {
       rtx disp = addr.disp;
 
@@ -6023,7 +6420,11 @@ csky_valid_fpuv2_mem_operand (rtx op)
 
        return false;
     }
-  return true;
+  else if (constraint[0] == 'Q')
+  /* Single reg is valid for 'Q'.  */
+    return true;
+
+  return false;
 }
 
 
@@ -6442,7 +6843,7 @@ ck803_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
     }
 }
 
-/* TARGET_RTX_COSTS helper for ck807+ arches.  */
+/* TARGET_RTX_COSTS helper for ck807/ck810 arches.  */
 
 static bool
 ck807_ck810_rtx_costs (rtx x, int code,
@@ -6473,6 +6874,52 @@ ck807_ck810_rtx_costs (rtx x, int code,
     }
 }
 
+/* TARGET_RTX_COSTS helper for ck860 arches.  */
+
+static bool
+ck860_rtx_costs (rtx x, int code, machine_mode mode,
+		 int outer_code ATTRIBUTE_UNUSED,
+		 int *total, bool speed ATTRIBUTE_UNUSED)
+{
+  switch (code)
+    {
+    case PLUS:
+      /* The costs of mula is 1 more than mult.  */
+      if (GET_CODE (XEXP (x, 0)) == MULT && REG_P (XEXP (x, 1)) && speed)
+	{
+	  rtx mul_op0 = XEXP (XEXP (x, 0), 0);
+	  rtx mul_op1 = XEXP (XEXP (x, 0), 1);
+	  if (REG_P (mul_op0) && REG_P (mul_op1))
+	    {
+	      *total = COSTS_N_INSNS (1);
+	      *total += rtx_cost (XEXP (x, 0), mode,
+				  (enum rtx_code) code, 0, speed);
+	      return true;
+	    }
+	}
+      return false;
+    case MULT:
+      if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
+	{
+	  HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
+	  if (val % 2 == 0 && val < 0xffffffff && val > 0)
+	    {
+	      *total = COSTS_N_INSNS (1);
+	      return true;
+	    }
+	}
+      return false;
+
+    case CONST:
+    case LABEL_REF:
+    case SYMBOL_REF:
+      *total = COSTS_N_INSNS (3);
+      return true;
+    default:
+      return false;
+    }
+}
+
 
 /* Implement TARGET_RTX_COSTS, to compute a (partial) cost for rtx X.
    Return true if the complete cost has been computed, and false if
@@ -6491,6 +6938,8 @@ csky_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
     return ck803_rtx_costs (x, code, outer_code, total, speed);
   else if (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
     return ck807_ck810_rtx_costs (x, code, outer_code, total, speed);
+  else if (CSKY_TARGET_ARCH (CK860))
+    return ck860_rtx_costs (x, code, mode, outer_code, total, speed);
   else
     gcc_unreachable ();
 }
@@ -6633,6 +7082,7 @@ csky_warn_func_return (tree decl)
 /* Implement TARGET_RETURN_IN_MEMORY to decide whether TYPE should be
    returned in memory (true) or in a register (false).
    FNTYPE is the type of the function making the call.  */
+
 static bool
 csky_return_in_memory (const_tree type,
 		       const_tree fntype ATTRIBUTE_UNUSED)
@@ -6646,6 +7096,7 @@ csky_return_in_memory (const_tree type,
    Dwarf models VFP registers as  64-bit or 128-bit registers default.
    GCC models tham as 32-bit registers, so we need to describe this to
    the DWARF generation code.  Other registers can use the default.  */
+
 static rtx
 csky_dwarf_register_span (rtx rtl)
 {
@@ -6659,11 +7110,15 @@ csky_dwarf_register_span (rtx rtl)
   if (!CSKY_VREG_P (regno))
     return NULL_RTX;
 
+  if (CSKY_VREG_HI_P (regno))
+    regno += 16;
+
   mode = GET_MODE (rtl);
   if (GET_MODE_SIZE (mode) < 8)
     return NULL_RTX;
 
-  if (TARGET_SOFT_FPU)
+
+  if (TARGET_SINGLE_FPU)
     {
       nregs = GET_MODE_SIZE (mode) / 4;
       for (i = 0; i < nregs; i += 2)
@@ -6684,9 +7139,18 @@ csky_dwarf_register_span (rtx rtl)
 	 as the CPU bit width. Transform the 64-bit FPU registers to
 	 32 bits here, and we will modify the unwind processing to
 	 fit CSKY architecture later.  */
-      nregs = GET_MODE_SIZE (mode) / 8;
-      for (i = 0; i < nregs; i++)
-	parts[i] = gen_rtx_REG (SImode, regno + i);
+      nregs = GET_MODE_SIZE (mode) / 4;
+      for (i = 0; i < nregs; i += 2)
+	if (TARGET_BIG_ENDIAN)
+	  {
+	    parts[i] = gen_rtx_REG (SImode, regno + i - 16);
+	    parts[i + 1] = gen_rtx_REG (SImode, regno + i);
+	  }
+	else
+	  {
+	    parts[i] = gen_rtx_REG (SImode, regno + i);
+	    parts[i + 1] = gen_rtx_REG (SImode, regno + i - 16);
+	  }
     }
 
   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nregs , parts));
@@ -6847,6 +7311,34 @@ csky_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
     pcum->is_stdarg = true;
 }
 
+
+/* Implement the TARGET_INIT_BUILTINS target macro.  */
+
+void
+csky_init_builtins (void)
+{
+  /* Inint fp16.  */
+  static tree csky_floatHF_type_node = make_node (REAL_TYPE);
+  TYPE_PRECISION (csky_floatHF_type_node) = GET_MODE_PRECISION (HFmode);
+  layout_type (csky_floatHF_type_node);
+  (*lang_hooks.types.register_builtin_type) (csky_floatHF_type_node, "__fp16");
+}
+
+
+/* Implement TARGET_MANGLE_TYPE.  */
+
+static const char *
+csky_mangle_type (const_tree type)
+{
+  if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+      && DECL_NAME (TYPE_NAME (type))
+      && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), "__fp16"))
+    return "__fp16";
+
+  /* Use the default mangling.  */
+  return NULL;
+}
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-csky.h"
diff --git a/gcc/config/csky/csky.h b/gcc/config/csky/csky.h
index c7590ab..f535c42 100644
--- a/gcc/config/csky/csky.h
+++ b/gcc/config/csky/csky.h
@@ -28,8 +28,17 @@
 #define CSKY_GENERAL_REGNO_P(N)			\
   ((N) < CSKY_NGPR_REGS && (int)(N) >= 0)
 
-#define CSKY_VREG_P(N)		     \
-  ((N) >= CSKY_FIRST_VFP_REGNUM && (N) <= CSKY_LAST_VFP_REGNUM)
+#define CSKY_VREG_LO_P(N) \
+  ((N) >= CSKY_FIRST_VFP_REGNUM \
+   && (N) <= CSKY_LAST_VFP_REGNUM)
+
+ #define CSKY_VREG_HI_P(N) \
+   ((N) >= CSKY_FIRST_VFP3_REGNUM \
+    && (N) <= CSKY_LAST_VFP3_REGNUM)
+
+ #define CSKY_VREG_P(N)    \
+   (CSKY_VREG_LO_P(N)     \
+    || CSKY_VREG_HI_P(N))
 
 #define CSKY_HILO_REG_P(N)   \
   ((N) == CSKY_HI_REGNUM || (N) == CSKY_LO_REGNUM)
@@ -124,7 +133,7 @@
   (optimize_size && TARGET_CONSTANT_POOL \
    && (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802)))
 #define TARGET_TLS \
-  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
+  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK860))
 
 /* Run-time Target Specification.  */
 #define TARGET_SOFT_FLOAT       (csky_float_abi == CSKY_FLOAT_ABI_SOFT)
@@ -133,7 +142,9 @@
 /* Use hardware floating point calling convention.  */
 #define TARGET_HARD_FLOAT_ABI   (csky_float_abi == CSKY_FLOAT_ABI_HARD)
 
-#define TARGET_SINGLE_FPU     (csky_fpu_index == TARGET_FPU_fpv2_sf)
+#define TARGET_SINGLE_FPU     (csky_fpu_index == TARGET_FPU_fpv2_sf \
+			       || csky_fpu_index == TARGET_FPU_fpv3_hsf \
+			       || csky_fpu_index == TARGET_FPU_fpv3_hf)
 #define TARGET_DOUBLE_FPU     (TARGET_HARD_FLOAT && !TARGET_SINGLE_FPU)
 
 #define FUNCTION_VARG_REGNO_P(REGNO)      \
@@ -142,13 +153,18 @@
 		CSKY_FIRST_VFP_REGNUM + CSKY_NPARM_FREGS - 1))
 
 #define CSKY_VREG_MODE_P(mode) \
-  ((mode) == SFmode || (mode) == DFmode)
+  ((mode) == SFmode || (mode) == DFmode \
+   || (CSKY_ISA_FEATURE(fpv3_hf) && (mode) == HFmode))
 
 #define FUNCTION_VARG_MODE_P(mode)  \
   (TARGET_HARD_FLOAT_ABI            \
    && CSKY_VREG_MODE_P(mode)        \
    && !(mode == DFmode && TARGET_SINGLE_FPU))
 
+#define TARGET_SUPPORT_FPV3 (CSKY_ISA_FEATURE (fpv3_hf)    \
+			     || CSKY_ISA_FEATURE (fpv3_sf) \
+			     || CSKY_ISA_FEATURE (fpv3_df))
+
 /* Number of loads/stores handled by ldm/stm.  */
 #define CSKY_MIN_MULTIPLE_STLD	3
 #define CSKY_MAX_MULTIPLE_STLD	12
@@ -427,7 +443,7 @@ typedef struct
  ******************************************************************/
 
 
-#define FIRST_PSEUDO_REGISTER 71
+#define FIRST_PSEUDO_REGISTER 202
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
@@ -456,7 +472,31 @@ typedef struct
  /*  reserved */							\
      1,	   1,								\
  /*  epc */								\
-     1									\
+     1,									\
+ /* vr16  vr17  vr18  vr19  vr20  vr21  vr22  vr23 */			\
+     0,    0,    0,    0,    0,    0,    0,    0,			\
+ /* vr24  vr25  vr26  vr27  vr28  vr29  vr30  vr31 */			\
+     0,    0,    0,    0,    0,    0,    0,    0 ,			\
+ /* reserved */								\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+ /* reserved */								\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+									\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+									\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+									\
+     1,    1,    1							\
 }
 
 /* Like `CALL_USED_REGISTERS' but used to overcome a historical
@@ -487,7 +527,31 @@ typedef struct
  /*  reserved */							\
      1,	   1,								\
  /*  epc */								\
-     1									\
+     1,									\
+ /*  vr16  vr17  vr18  vr19  vr20  vr21  vr22  vr23*/			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  vr24  vr25 vr26  vr27  vr28  vr29	 vr30  vr31 */			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /*  reserved */							\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
+ /* reserved */								\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+									\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+									\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+     1,    1,    1,    1,    1,    1,    1,    1,			\
+									\
+     1,    1,    1							\
 }
 
 #define REGISTER_NAMES							\
@@ -510,7 +574,37 @@ typedef struct
   "vr0", "vr1", "vr2",	"vr3",	"vr4",	"vr5",	"vr6",	"vr7",		\
   "vr8", "vr9", "vr10", "vr11", "vr12", "vr13", "vr14", "vr15",		\
   "reserved", "reserved",						\
-  "epc"									\
+  "epc",								\
+  /* V registers: 71~86 */						\
+  "vr16", "vr17", "vr18", "vr19", "vr20", "vr21", "vr22", "vr23",	\
+  "vr24", "vr25", "vr26", "vr27", "vr28", "vr29", "vr30", "vr31",	\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved",								\
+  /* reserved: 87~201*/							\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved",						\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved",						\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved", "reserved", "reserved", "reserved",		\
+  "reserved", "reserved",						\
+  "reserved", "reserved", "reserved"					\
 }
 
 /* Table of additional register names to use in user input.  */
@@ -569,9 +663,16 @@ typedef struct
      52,   53,	 54,   55,   56,   57,	 58,   59,		\
 /*  vr8	  vr9	vr10  vr11  vr12  vr13	vr14  vr15 */		\
      60,   61,	 62,   63,   64,   65,	 66,   67,		\
+/*  vr16  vr17  vr18  vr18  vr20  vr21	vr22  vr23 */		\
+     71,   72,	 73,   74,   75,   76,	 77,   78,		\
+/*  vr24  vr25	vr26  vr27  vr28  vr28	vr30  vr31 */		\
+     79,   80,	 81,   82,   83,   84,	 85,   86,		\
 /*  reserved  */						\
      36,   37,	 38,   39,   40,   41,	 42,   43,		\
      44,   45,	 46,   47,   48,   49,	 50,   51,		\
+/*  reserved  */						\
+     87,   88,	 89,   90,   91,   92,	 93,   94,		\
+     95,   96,	 97,   98,   99,   100,  101,  102,		\
 /*  sp	  tls	reserved     c	   reserved	    epc */	\
      14,   31,	 32,	     33,   68,	 69,	     70	 }
 
@@ -616,21 +717,34 @@ enum reg_class
 
 /* Define which registers fit in which classes.  This is an initializer
    for a vector of HARD_REG_SET of length N_REG_CLASSES.  */
-#define REG_CLASS_CONTENTS					     \
-{								     \
-  {0x00000000, 0x00000000, 0x00000000 },  /* NO_REGS	       */    \
-  {0x000000FF, 0x00000000, 0x00000000 },  /* MINI_REGS	       */    \
-  {0x00004000, 0x00000000, 0x00000000 },  /* SP_REGS	       */    \
-  {0x0000FFFF, 0x00000000, 0x00000000 },  /* LOW_REGS	       */    \
-  {0xFFFFFFFF, 0x00000000, 0x00000000 },  /* GENERAL_REGS      */    \
-  {0x00000000, 0x00000002, 0x00000000 },  /* C_REGS	       */    \
-  {0x00000000, 0x00000004, 0x00000000 },  /* HI_REG	       */    \
-  {0x00000000, 0x00000008, 0x00000000 },  /* LO_REG	       */    \
-  {0x00000000, 0x0000000c, 0x00000000 },  /* HILO_REGS	       */    \
-  {0x00000000, 0xFFF00000, 0x0000000F },  /* V_REGS	       */    \
-  {0x00000000, 0x00000000, 0x00000040 },  /* OTHER_REGS	       */    \
-  {0x00000000, 0x0FF00001, 0x00000030 },  /* RESERVE_REGS      */    \
-  {0xFFFFFFFF, 0xFFFFFFFF, 0x0000007F },  /* ALL_REGS	       */    \
+#define REG_CLASS_CONTENTS						      \
+{									      \
+  {0x00000000, 0x00000000, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* NO_REGS	 */   \
+  {0x000000FF, 0x00000000, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* MINI_REGS     */   \
+  {0x00004000, 0x00000000, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* SP_REGS	 */   \
+  {0x0000FFFF, 0x00000000, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* LOW_REGS      */   \
+  {0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* GENERAL_REGS  */   \
+  {0x00000000, 0x00000002, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* C_REGS	 */   \
+  {0x00000000, 0x00000004, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* HI_REG	 */   \
+  {0x00000000, 0x00000008, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* LO_REG	 */   \
+  {0x00000000, 0x0000000c, 0x00000000, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* HILO_REGS     */   \
+  {0x00000000, 0xFFF00000, 0x007FFF8F, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* V_REGS	 */   \
+  {0x00000000, 0x00000000, 0x00000040, 0x00000000,			      \
+   0x00000000, 0x00000000, 0x00000000},			/* OTHER_REGS    */   \
+  {0x00000000, 0x000FFFF1, 0xFF800030, 0xFFFFFFFF,			      \
+   0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF},			/* RESERVE_REGS  */   \
+  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,			      \
+   0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF},			/* ALL_REGS      */   \
 }
 
 /* Return register class from regno.  */
diff --git a/gcc/config/csky/csky.md b/gcc/config/csky/csky.md
index 8bb3b2b..c27d627 100644
--- a/gcc/config/csky/csky.md
+++ b/gcc/config/csky/csky.md
@@ -32,6 +32,8 @@
    (CSKY_FIRST_RET_REGNUM		0)
    (CSKY_FIRST_VFP_REGNUM		52)
    (CSKY_LAST_VFP_REGNUM		67)
+   (CSKY_FIRST_VFP3_REGNUM		71)
+   (CSKY_LAST_VFP3_REGNUM		86)
    (CSKY_FIRST_HIGH_REGNUM		16)
    (CSKY_LAST_HIGH_REGNUM		31)
    (CSKY_FIRST_MINI_REGNUM		0)
@@ -423,85 +425,6 @@
    (set_attr "type" "alu,alu,alu,load,load,store")]
 )
 
-;; Float mov instructions.
-
-(define_expand "movsf"
-  [(set (match_operand:SF 0 "general_operand" "")
-	(match_operand:SF 1 "general_operand" ""))]
-  ""
-  "
-  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
-    operands[1] = force_reg (SFmode, operands[1]);
-  "
-)
-
-;; FIXME: maybe the vreg load/stores should have their own type attr.
-(define_insn "*csky_movsf_fpv2"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v")
-	(match_operand:SF 1 "general_operand"	   " b,r,r,v,m,mF,r,v,Q,v,m"))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "* return csky_output_move (insn, operands, SFmode);"
-  [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4")
-   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
-)
-
-(define_insn "*ck801_movsf"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
-	(match_operand:SF 1 "general_operand"	   " r,m,mF,r"))]
-  "CSKY_ISA_FEATURE (E1)"
-  "* return csky_output_ck801_move (insn, operands, SFmode);"
-  [(set_attr "length" "2,4,4,4")
-   (set_attr "type" "alu,load,load,store")]
-)
-
-(define_insn "*csky_movsf"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
-	(match_operand:SF 1 "general_operand"	   " b,r,m,mF,r"))]
-  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_sf)"
-  "* return csky_output_move (insn, operands, SFmode);"
- [(set_attr "length" "2,4,4,4,4")
-  (set_attr "type" "alu,alu,load,load,store")]
-)
-
-
-(define_expand "movdf"
-  [(set (match_operand:DF 0 "general_operand" "")
-	(match_operand:DF 1 "general_operand" ""))]
-  ""
-  "
-  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
-      operands[1] = force_reg (DFmode, operands[1]);
-  "
-)
-
-;; FIXME: maybe the vreg load/stores should have their own type attr.
-(define_insn "*csky_movdf_fpv2"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v")
-	(match_operand:DF 1 "general_operand"	    "b,r,r,v,m,mF,r,v,Q,v,m"))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "* return csky_output_movedouble (operands, DFmode);"
-  [(set_attr "length" "4,8,8,8,8,8,8,8,8,8,8")
-   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
-)
-
-(define_insn "*ck801_movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
-	(match_operand:DF 1 "general_operand"	   " r,m,mF,r"))]
-  "CSKY_ISA_FEATURE (E1)"
-  "* return csky_output_ck801_movedouble (operands, DFmode);"
-  [(set_attr "length" "4,8,8,8")
-   (set_attr "type" "alu,load,load,store")]
-)
-
-(define_insn "*csky_movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
-	(match_operand:DF 1 "general_operand"	   " b,r,m,mF,r"))]
-  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_df)"
-  "* return csky_output_movedouble (operands, DFmode);"
- [(set_attr "length" "4,8,8,8,8")
-  (set_attr "type" "alu,alu,load,load,store")]
-)
-
 ;; The only CCmode move supported is a nop.  Without this pattern,
 ;; CSE is unable to eliminate redundant comparisons in conditional
 ;; execution expressions.
@@ -522,7 +445,7 @@
 
 (define_expand "movsicc"
   [(set (match_operand 0 "register_operand" "")
-	(if_then_else:SI (match_operand	   1 "ordered_comparison_operator" "")
+	(if_then_else:SI (match_operand	   1 "comparison_operator" "")
 			 (match_operand:SI 2 "register_operand" "")
 			 (match_operand:SI 3 "register_operand" "")))]
   "CSKY_ISA_FEATURE (E2)"
@@ -1321,7 +1244,7 @@
 
 (define_expand "addsicc"
   [(match_operand:SI 0 "register_operand" "")
-   (match_operand    1 "ordered_comparison_operator" "")
+   (match_operand    1 "comparison_operator" "")
    (match_operand:SI 2 "register_operand" "")
    (match_operand:SI 3 "csky_literal_K_Uh_operand" "")]
   "CSKY_ISA_FEATURE (E2)"
@@ -3316,9 +3239,9 @@
 
 (define_expand "untyped_call"
   [(parallel [(call (match_operand 0 "" "")
-        (const_int 0))
-        (match_operand 1 "" "")
-        (match_operand 2 "" "")])]
+	(const_int 0))
+	(match_operand 1 "" "")
+	(match_operand 2 "" "")])]
   ""
 {
   int i;
@@ -3349,11 +3272,25 @@
   ""
   [(set_attr "length" "0")])
 
-(define_insn "*call_value_internal_vs"
-  [(set (match_operand:SF               0 "register_operand"          "=v,v,v")
+(define_insn "*call_value_internal_vh"
+  [(set (match_operand:HF               0 "register_operand"          "=v,v,v")
         (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
               (match_operand 2 "" "")))
    (clobber (reg:SI CSKY_LR_REGNUM))]
+  "TARGET_HARD_FLOAT_ABI && CSKY_ISA_FEATURE (fpv3_hf)"
+  "@
+    jsr\t%1
+    jsr\t%1
+    jbsr\t%1"
+  [(set_attr "length" "2,4,4")
+   (set_attr "type"   "call_jsr,call_jsr,call")]
+)
+
+(define_insn "*call_value_internal_vs"
+  [(set (match_operand:SF	       0 "register_operand"	  "=v,v,v")
+	(call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
+	      (match_operand 2 "" "")))
+   (clobber (reg:SI CSKY_LR_REGNUM))]
   "TARGET_HARD_FLOAT_ABI"
   "@
     jsr\t%1
@@ -3364,9 +3301,9 @@
 )
 
 (define_insn "*call_value_internal_vd"
-  [(set (match_operand:DF               0 "register_operand"          "=v,v,v")
-        (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
-              (match_operand 2 "" "")))
+  [(set (match_operand:DF	       0 "register_operand"	  "=v,v,v")
+	(call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
+	      (match_operand 2 "" "")))
    (clobber (reg:SI CSKY_LR_REGNUM))]
   "TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
   "@
@@ -3378,18 +3315,18 @@
 )
 
 (define_insn "*call_value_internal_pic_vs"
-  [(set (match_operand:SF               0 "register_operand"    "=v")
-        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
-                      (match_operand    2 "" "")))
+  [(set (match_operand:SF	       0 "register_operand"    "=v")
+	(call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
+		      (match_operand    2 "" "")))
    (clobber (reg:SI CSKY_LR_REGNUM))]
   "flag_pic && TARGET_HARD_FLOAT_ABI"
   "* return csky_output_call (operands, 1);"
 )
 
 (define_insn "*call_value_internal_pic_vd"
-  [(set (match_operand:DF               0 "register_operand"    "=v")
-        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
-                      (match_operand    2 "" "")))
+  [(set (match_operand:DF	       0 "register_operand"    "=v")
+	(call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
+		      (match_operand    2 "" "")))
    (clobber (reg:SI CSKY_LR_REGNUM))]
   "flag_pic && TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
   "* return csky_output_call (operands, 1);"
diff --git a/gcc/config/csky/csky_cores.def b/gcc/config/csky/csky_cores.def
index 8309e99..fcf42a4 100644
--- a/gcc/config/csky/csky_cores.def
+++ b/gcc/config/csky/csky_cores.def
@@ -38,6 +38,8 @@ CSKY_ARCH ("ck807",  ck807,  CK807,
 	   CSKY_ISA_FEAT (CSKY_ISA_CK807) CSKY_ISA_FEAT (CSKY_ISA_DSP))
 CSKY_ARCH ("ck810",  ck810,  CK810,
 	   CSKY_ISA_FEAT (CSKY_ISA_CK810) CSKY_ISA_FEAT (CSKY_ISA_DSP))
+CSKY_ARCH ("ck860",  ck860,  CK860,
+	   CSKY_ISA_FEAT (CSKY_ISA_CK860))
 #endif
 
 
@@ -181,6 +183,12 @@ CSKY_CORE ("ck810ft",  ck810ff,	 ck810ft,  CK810,
 	   CSKY_ISA_FEAT_NONE)
 CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
 	   CSKY_ISA_FEAT_NONE)
+
+/* ck860 Architecture Processors */
+CSKY_CORE("ck860",    ck860,    ck860,    CK860,
+	  CSKY_ISA_FEAT_NONE)
+CSKY_CORE("ck860f",   ck860f,   ck860f,   CK860,
+	  CSKY_ISA_FEAT_NONE)
 #endif
 
 
@@ -196,4 +204,9 @@ CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
 CSKY_FPU ("fpv2_sf",   fpv2_sf,	  CSKY_ISA_FEAT (CSKY_ISA_FPv2_SF))
 CSKY_FPU ("fpv2",      fpv2,	  CSKY_ISA_FEAT (CSKY_ISA_FPv2))
 CSKY_FPU ("fpv2_divd", fpv2_divd, CSKY_ISA_FEAT (CSKY_ISA_FPv2_DIVD))
+
+CSKY_FPU ("fpv3_hf",   fpv3_hf,   CSKY_ISA_FEAT (CSKY_ISA_FPv3_HF))
+CSKY_FPU ("fpv3_hsf",  fpv3_hsf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_HSF))
+CSKY_FPU ("fpv3_sdf",  fpv3_sdf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_SDF))
+CSKY_FPU ("fpv3",      fpv3,      CSKY_ISA_FEAT (CSKY_ISA_FPv3))
 #endif
diff --git a/gcc/config/csky/csky_insn_fpu.md b/gcc/config/csky/csky_insn_fpu.md
index c1e78af..e0d01ab 100644
--- a/gcc/config/csky/csky_insn_fpu.md
+++ b/gcc/config/csky/csky_insn_fpu.md
@@ -18,528 +18,314 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.  */
 
-;; -------------------------------------------------------------------------
-;; Float Abs instructions
-;; -------------------------------------------------------------------------
+(define_c_enum "unspec" [
+  UNSPEC_FLOOR
+  UNSPEC_CEIL
+  UNSPEC_BTRUNC
+  UNSPEC_RINT
+])
 
-(define_insn "abssf2"
-  [(set (match_operand:SF	  0 "register_operand" "=v,r")
-	(abs:SF (match_operand:SF 1 "register_operand" "v, r")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "@
-    fabss\t%0, %1
-    bclri\t%0, %1, 31")
+(define_c_enum "unspecv" [
+  VUNSPEC_GET_FCR     ; Represent fetch of FCR content.
+  VUNSPEC_SET_FCR     ; Represent assign of FCR content.
+  VUNSPEC_INS_FCR     ; Represent insert of FCR content.
+])
 
-(define_insn "absdf2"
-  [(set (match_operand:DF	  0 "register_operand" "=v")
-	(abs:DF (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fabsd\t%0, %1")
+(define_mode_iterator F3ANY [HF SF DF])
+(define_mode_attr f3t [(HF "16") (SF "32") (DF "64")])
 
+(define_mode_iterator SFDF [SF DF])
+(define_mode_attr f2t [(SF "32") (DF "64")])
 
-;; -------------------------------------------------------------------------
-;; Float Neg instructions
-;; -------------------------------------------------------------------------
+(define_code_iterator FCMPZ [ne ge lt gt le])
+(define_code_attr zero_inst [(ne "nez") (ge "hsz") (lt "ltz") (gt "hz") (le "lsz")])
 
-(define_insn "negsf2"
-  [(set (match_operand:SF	  0 "register_operand" "=v")
-	(neg:SF (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnegs\t%0, %1")
+(define_code_iterator FCMP [ne ge lt])
+(define_code_attr reg_inst [(ne "ne") (ge "hs") (lt "lt")])
 
-(define_insn "negdf2"
-  [(set (match_operand:DF	  0 "register_operand" "=v")
-	(neg:DF (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnegd\t%0, %1")
+(define_code_iterator FIX_SU [fix unsigned_fix])
+(define_code_attr fixsuop [(fix "")  (unsigned_fix "uns")])
+(define_code_attr fixsu   [(fix "s") (unsigned_fix "u")])
 
+(define_code_iterator FLOAT_SU [float unsigned_float])
+(define_code_attr floatsuop [(float "")  (unsigned_float "uns")])
+(define_code_attr floatsu   [(float "s") (unsigned_float "u")])
 
-;; -------------------------------------------------------------------------
-;; Float Sqrt instructions
-;; -------------------------------------------------------------------------
+(define_int_iterator FRM  [UNSPEC_FLOOR
+			   UNSPEC_CEIL UNSPEC_RINT])
 
-(define_insn "sqrtsf2"
-  [(set (match_operand:SF	   0 "register_operand" "=v")
-	(sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fsqrts\t%0, %1")
+(define_int_iterator FRMF [UNSPEC_FLOOR
+			   UNSPEC_CEIL UNSPEC_BTRUNC])
 
-(define_insn "sqrtdf2"
-  [(set (match_operand:DF	   0 "register_operand" "=v")
-	(sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_divd)"
- "fsqrtd\t%0, %1")
+(define_int_attr frm_pattern [(UNSPEC_FLOOR "floor")
+			      (UNSPEC_CEIL "ceil")   (UNSPEC_BTRUNC "btrunc")
+			      (UNSPEC_RINT "rint")])
+
+(define_int_attr rm [(UNSPEC_FLOOR ".rni")
+		     (UNSPEC_CEIL ".rpi")  (UNSPEC_BTRUNC ".rz")
+		     (UNSPEC_RINT "")])
 
 
 ;; -------------------------------------------------------------------------
-;; Float Add instructions
+;; Float mov instructions
 ;; -------------------------------------------------------------------------
 
-(define_insn "addsf3"
-  [(set (match_operand:SF	   0 "register_operand" "=v")
-	(plus:SF (match_operand:SF 1 "register_operand" "v")
-		 (match_operand:SF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fadds\t%0, %1, %2")
+(define_expand "movhf"
+  [(set (match_operand:HF 0 "general_operand" "")
+	(match_operand:HF 1 "general_operand" ""))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "
+  {
+    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
+      {
+	operands[1] = force_reg (HFmode, operands[1]);
+      }
+  }
+")
+
+(define_expand "mov<mode>"
+  [(set (match_operand:SFDF 0 "general_operand" "")
+	(match_operand:SFDF 1 "general_operand" ""))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>)
+   || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "
+  {
+    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
+      {
+	operands[1] = force_reg (<MODE>mode, operands[1]);
+      }
+  }
+")
+
+;; Move float value with general register.
+
+(define_insn "*e2_movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
+       (match_operand:SF 1 "general_operand"      " b,r,m,mF,r"))]
+  "CSKY_ISA_FEATURE (E2)
+   && !CSKY_ISA_FEATURE (fpv2_sf)
+   && !CSKY_ISA_FEATURE (fpv3_sf)"
+  "* return csky_output_move (insn, operands, SFmode);"
+ [(set_attr "length" "2,4,4,4,4")
+  (set_attr "type" "alu,alu,load,load,store")]
+)
+
+(define_insn "*e2_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
+       (match_operand:DF 1 "general_operand"      " b,r,m,mF,r"))]
+  "CSKY_ISA_FEATURE (E2)
+   && !CSKY_ISA_FEATURE (fpv2_df)
+   && !CSKY_ISA_FEATURE (fpv3_df)"
+  "* return csky_output_movedouble (operands, DFmode);"
+ [(set_attr "length" "4,8,8,8,8")
+  (set_attr "type" "alu,alu,load,load,store")]
+)
 
-(define_insn "adddf3"
-  [(set (match_operand:DF	   0 "register_operand" "=v")
-	(plus:DF (match_operand:DF 1 "register_operand" "v")
-		 (match_operand:DF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "faddd\t%0, %1, %2")
+(define_insn "*e1_movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
+	(match_operand:SF 1 "general_operand"      " r,m,mF,r"))]
+  "CSKY_ISA_FEATURE (E1)"
+  "* return csky_output_ck801_move (insn, operands, SFmode);"
+  [(set_attr "length" "2,4,4,4")
+   (set_attr "type" "alu,load,load,store")]
+)
 
+(define_insn "*e1_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
+	(match_operand:DF 1 "general_operand"      " r,m,mF,r"))]
+  "CSKY_ISA_FEATURE (E1)"
+  "* return csky_output_ck801_movedouble (operands, DFmode);"
+  [(set_attr "length" "4,8,8,8")
+   (set_attr "type" "alu,load,load,store")]
+)
 
 ;; -------------------------------------------------------------------------
-;; Float Sub instructions
+;; Float Mul instructions
 ;; -------------------------------------------------------------------------
 
-(define_insn "subsf3"
-  [(set (match_operand:SF	    0 "register_operand" "=v")
-	(minus:SF (match_operand:SF 1 "register_operand" "v")
-		  (match_operand:SF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fsubs\t%0, %1, %2")
+(define_expand "mulhf3"
+  [(set (match_operand:HF	    0 "register_operand" "=v")
+	(mult:HF (match_operand:HF   1 "register_operand" "v")
+		 (match_operand:HF   2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
 
-(define_insn "subdf3"
-  [(set (match_operand:DF	    0 "register_operand" "=v")
-	(minus:DF (match_operand:DF 1 "register_operand" "v")
-		  (match_operand:DF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fsubd\t%0, %1, %2")
+(define_expand "mul<mode>3"
+  [(set (match_operand:SFDF	    0 "register_operand" "=v")
+	(mult:SFDF (match_operand:SFDF   1 "register_operand" "v")
+		 (match_operand:SFDF   2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>)
+  || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
 
+(define_expand "fma<mode>4"
+  [(set (match_operand:F3ANY	    0 "register_operand" "=v")
+	(fma:F3ANY (match_operand:F3ANY  1 "register_operand" "v")
+		   (match_operand:F3ANY  2 "register_operand" "v")
+		   (match_operand:F3ANY  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
 
 ;; -------------------------------------------------------------------------
-;; Float Mul instructions
+;; Float ADD SUB NEG ABS instructions
 ;; -------------------------------------------------------------------------
 
-(define_insn "mulsf3"
-  [(set (match_operand:SF	   0 "register_operand" "=v")
-	(mult:SF (match_operand:SF 1 "register_operand" "v")
-		 (match_operand:SF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fmuls\t%0, %1, %2")
-
-(define_insn "muldf3"
-  [(set (match_operand:DF	   0 "register_operand" "=v")
-	(mult:DF (match_operand:DF 1 "register_operand" "v")
-		 (match_operand:DF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fmuld\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmulsf3_1"
-  [(set (match_operand:SF		   0 "register_operand" "=v")
-	(mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
-		 (match_operand:SF	   2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
-  "fnmuls\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmulsf3_2"
-  [(set (match_operand:SF		   0 "register_operand" "=v")
-	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
-			 (match_operand:SF 2 "register_operand" "v"))))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnmuls\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmuldf3_1"
-  [(set (match_operand:DF		   0 "register_operand" "=v")
-	(mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
-		 (match_operand:DF	   2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
- "fnmuld\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmuldf3_2"
-  [(set (match_operand:DF		   0 "register_operand" "=v")
-	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
-			 (match_operand:DF 2 "register_operand" "v"))))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnmuld\t%0, %1, %2")
+(define_expand "addhf3"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(plus:HF (match_operand:HF  1 "register_operand" "")
+		 (match_operand:HF  2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
+
+(define_expand "add<mode>3"
+  [(set (match_operand:SFDF	     0 "register_operand" "")
+	(plus:SFDF (match_operand:SFDF  1 "register_operand" "")
+		   (match_operand:SFDF  2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
+(define_expand "subhf3"
+  [(set (match_operand:HF	    0 "register_operand" "")
+	(minus:HF (match_operand:HF  1 "register_operand" "")
+		  (match_operand:HF  2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
 
-;; -------------------------------------------------------------------------
-;; Float Div instructions
-;; -------------------------------------------------------------------------
+(define_expand "sub<mode>3"
+  [(set (match_operand:SFDF	      0 "register_operand" "")
+	(minus:SFDF (match_operand:SFDF  1 "register_operand" "")
+		    (match_operand:SFDF  2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
-(define_expand "divsf3"
-  [(set (match_operand:SF	  0 "register_operand" "")
-	(div:SF (match_operand:SF 1 "csky_arith_float1_operand" "")
-		(match_operand:SF 2 "register_operand" "")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "")
+(define_expand "abshf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(abs:HF (match_operand:HF   1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
 
-(define_insn "*fpuv2_divsf3"
-  [(set (match_operand:SF	  0 "register_operand" "=v")
-	(div:SF (match_operand:SF 1 "register_operand" "v")
-		(match_operand:SF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fdivs\t%0, %1, %2")
-
-(define_insn "*fpuv2_1_divsf3"
-  [(set (match_operand:SF	  0 "register_operand"		"=v")
-	(div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
-		(match_operand:SF 2 "register_operand"		"v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "frecips\t%0, %2")
-
-
-(define_expand "divdf3"
-  [(set (match_operand:DF 0 "register_operand" "")
-	(div:DF (match_operand:DF 1 "csky_arith_float1_operand" "")
-		(match_operand:DF 2 "register_operand" "")))]
-  "CSKY_ISA_FEATURE (fpv2_divd)"
-  "")
+(define_expand "abs<mode>2"
+  [(set (match_operand:SFDF	     0 "register_operand" "")
+	(abs:SFDF (match_operand:SFDF   1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
-(define_insn "*fpuv2_divdf3"
-  [(set (match_operand:DF	  0 "register_operand" "=v")
-	(div:DF (match_operand:DF 1 "register_operand" "v")
-		(match_operand:DF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_divd)"
-  "fdivd\t%0, %1, %2")
+(define_expand "neghf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(neg:HF (match_operand:HF   1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
 
-(define_insn "*fpuv2_1_divdf3"
-  [(set (match_operand:DF	  0 "register_operand"		"=v")
-	(div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
-		(match_operand:DF 2 "register_operand"		"v")))]
-  "CSKY_ISA_FEATURE (fpv2_divd)"
-  "frecipd\t%0, %2")
+(define_expand "neg<mode>2"
+  [(set (match_operand:SFDF	   0 "register_operand" "")
+	(neg:SFDF (match_operand:SFDF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
+(define_expand "sqrthf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(sqrt:HF (match_operand:HF  1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
+
+(define_expand "sqrt<mode>2"
+  [(set (match_operand:SFDF	    0 "register_operand" "")
+	(sqrt:SFDF (match_operand:SFDF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
 ;; -------------------------------------------------------------------------
-;; Float add(sub) with mult instructions
+;; Float div instructions
 ;; -------------------------------------------------------------------------
 
-;; vrz <= vrz + vrx * vry
-(define_insn "*fpuv2_fmacs"
-  [(set (match_operand:SF		    0 "register_operand" "=v")
-	(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
-			  (match_operand:SF 2 "register_operand" "v"))
-		 (match_operand:SF	    3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fmacs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fmacd"
-  [(set (match_operand:DF		    0 "register_operand" "=v")
-	(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
-			  (match_operand:DF 2 "register_operand" "v"))
-		 (match_operand:DF	    3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fmacd\t%0, %1, %2")
-
-;; vrz <= vrz - vrx * vry
-(define_insn "*fpuv2_fnmacs"
-  [(set (match_operand:SF		     0 "register_operand" "=v")
-	(minus:SF (match_operand:SF	     1 "register_operand" "0")
-		  (mult:SF (match_operand:SF 2 "register_operand" "v")
-			   (match_operand:SF 3 "register_operand" "v"))))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnmacs\t%0, %2, %3")
-
-(define_insn "*fpuv2_fnmacd"
-  [(set (match_operand:DF		     0 "register_operand" "=v")
-	(minus:DF (match_operand:DF	     1 "register_operand" "0")
-		  (mult:DF (match_operand:DF 2 "register_operand" "v")
-			   (match_operand:DF 3 "register_operand" "v"))))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnmacd\t%0, %2, %3")
-
-;; vrz <= vrx * vry - vrz
-(define_insn "*fpuv2_fmscs"
-  [(set (match_operand:SF		     0 "register_operand" "=v")
-	(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
-			   (match_operand:SF 2 "register_operand" "v"))
-		  (match_operand:SF	     3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fmscd"
-  [(set (match_operand:DF 0 "register_operand" "=v")
-	(minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
-			   (match_operand:DF 2 "register_operand" "v"))
-		  (match_operand:DF 3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fmscd\t%0, %1, %2")
-
-;; vrz = - (vrz + vrx * vry)
-(define_insn "*fpuv2_fnmscs_1"
-  [(set (match_operand:SF			     0 "register_operand" "=v")
-	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
-			   (match_operand:SF	     2 "register_operand" "v"))
-		  (match_operand:SF		     3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscs_2"
-  [(set (match_operand:SF			    0 "register_operand" "=v")
-	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
-				  (match_operand:SF 2 "register_operand" "v"))
-			 (match_operand:SF	    3 "register_operand" "0"))))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscd_1"
-  [(set (match_operand:DF 0 "register_operand" "=v")
-	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
-			   (match_operand:DF 2 "register_operand" "v"))
-		  (match_operand:DF 3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnmscd\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscd_2"
-  [(set (match_operand:DF 0 "register_operand" "=v")
-	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
-				  (match_operand:DF 2 "register_operand" "v"))
-			 (match_operand:DF 3 "register_operand" "0"))))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnmscd\t%0, %1, %2")
+(define_expand "div<mode>3"
+  [(set (match_operand:SFDF	   0 "register_operand" "")
+	(div:SFDF (match_operand:SFDF 1 "csky_arith_float1_operand" "")
+		  (match_operand:SFDF 2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
 
+(define_expand "divhf3"
+ [(set (match_operand:HF 0 "register_operand" "")
+       (div:HF (match_operand:HF 1 "csky_arith_float1_operand" "")
+	       (match_operand:HF 2 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
 
 ;; -------------------------------------------------------------------------
 ;; Float compare instructions
 ;; -------------------------------------------------------------------------
 
-(define_expand "cbranchsf4"
+(define_expand "cbranch<mode>4"
   [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
-			     [(match_operand:SF 1 "register_operand")
-			      (match_operand:SF 2 "csky_compare_operand_float")])
+			    [(match_operand:SFDF 1 "register_operand")
+			     (match_operand:SFDF 2 "csky_compare_operand_float")])
 			   (label_ref (match_operand 3 ""))
 			   (pc)))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "
-  {
-    enum rtx_code code = GET_CODE (operands[0]);
-    bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
+"CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+"{
+  enum rtx_code code = GET_CODE (operands[0]);
+  bool invert;
 
-    if (invert)
-      emit_jump_insn (gen_csky_jbf (operands[3]));
-    else
-      emit_jump_insn (gen_csky_jbt (operands[3]));
+  invert = csky_emit_compare_float (code, operands[1], operands[2]);
 
-    DONE;
-  }")
-
-(define_insn "*fpuv2_unordered"
-  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
-				  (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpuos\t%0, %1")
-
-(define_insn "*fpuv2_unordered_zero"
-  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
-				  (match_operand:SF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpuos\t%0, %0")
-
-(define_insn "*fpuv2_ne"
-  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpnes\t%0, %1")
-
-(define_insn "*fpuv2_gt"
-  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmplts\t%1, %0")
-
-(define_insn "*fpuv2_ge"
-  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmphss\t%0, %1")
-
-(define_insn "*fpuv2_lt"
-  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmplts\t%0, %1")
-
-(define_insn "*fpuv2_le"
-  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmphss\t%1, %0")
-
-(define_insn "*fpuv2_gez"
-  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand"	   "v")
-			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpzhss\t%0")
-
-(define_insn "*fpuv2_nez"
-  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand"	   "v")
-			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpznes\t%0")
-
-
-(define_expand "cbranchdf4"
-  [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
-			     [(match_operand:DF 1 "register_operand")
-			      (match_operand:DF 2 "csky_compare_operand_float")])
-			   (label_ref (match_operand 3 ""))
-			   (pc)))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "
-  {
-    enum rtx_code code = GET_CODE (operands[0]);
-    bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
+  if (invert)
+    emit_jump_insn (gen_csky_jbf (operands[3]));
+  else
+    emit_jump_insn (gen_csky_jbt (operands[3]));
 
-    if (invert)
-      emit_jump_insn (gen_csky_jbf (operands[3]));
-    else
-      emit_jump_insn (gen_csky_jbt (operands[3]));
+  DONE;
 
-    DONE;
 }")
 
-(define_insn "*fpuv2_dunordered"
-  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
-				  (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpuod\t%0, %1")
-
-(define_insn "*fpuv2_dunordered_zero"
-  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
-				  (match_operand:DF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpuod\t%0, %0")
-
-(define_insn "*fpuv2_dne"
-  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpned\t%0, %1")
-
-(define_insn "*fpuv2_dgt"
-  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpltd\t%1, %0")
-
-(define_insn "*fpuv2_dge"
-  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmphsd\t%0, %1")
-
-(define_insn "*fpuv2_dlt"
-  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpltd\t%0, %1")
-
-(define_insn "*fpuv2_dle"
-  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmphsd\t%1, %0")
-
-(define_insn "*fpuv2_dgez"
-  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand"	   "v")
-			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpzhsd\t%0")
-
-(define_insn "*fpuv2_dnez"
-  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand"	   "v")
-			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpzned\t%0")
+(define_expand "cbranchhf4"
+  [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
+			    [(match_operand:HF 1 "register_operand")
+			     (match_operand:HF 2 "csky_compare_operand_float")])
+			   (label_ref (match_operand 3 ""))
+			   (pc)))]
+"CSKY_ISA_FEATURE(fpv3_hf)"
+"{
+  enum rtx_code code = GET_CODE (operands[0]);
+  bool invert;
 
+  invert = csky_emit_compare_float (code, operands[1], operands[2]);
 
-;; -------------------------------------------------------------------------
-;; Float convert instructions
-;; -------------------------------------------------------------------------
+  if (invert)
+    emit_jump_insn (gen_csky_jbf (operands[3]));
+  else
+    emit_jump_insn (gen_csky_jbt (operands[3]));
 
-;; DF <- SF
-(define_insn "extendsfdf2"
-  [(set (match_operand:DF		   0 "register_operand" "=v")
-	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fstod\t%0, %1")
-
-;; SF <- DF
-(define_insn "truncdfsf2"
-  [(set (match_operand:SF		     0 "register_operand" "=v")
-	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fdtos\t%0, %1")
-
-;; SF <- SI
-(define_insn "floatsisf2"
-  [(set (match_operand:SF	    0 "register_operand" "=v")
-	(float:SF (match_operand:SI 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fsitos\t%0, %1")
-
-;; DF <- SI
-(define_insn "floatsidf2"
-  [(set (match_operand:DF	    0 "register_operand" "=v")
-	(float:DF (match_operand:SI 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fsitod\t%0, %1")
-
-;; SF <- unsigned SI
-(define_insn "floatunssisf2"
-  [(set (match_operand:SF		     0 "register_operand" "=v")
-	(unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fuitos\t%0, %1")
-
-;; DF <- unsigned SI
-(define_insn "floatunssidf2"
-  [(set (match_operand:DF		     0 "register_operand" "=v")
-	(unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fuitod\t%0, %1")
-
-;; SI <- SF
-(define_insn "fix_truncsfsi2"
-  [(set (match_operand:SI	  0 "register_operand" "=v")
-	(fix:SI (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fstosi.rz\t%0, %1")
-
-;; SI <- DF
-(define_insn "fix_truncdfsi2"
-  [(set (match_operand:SI	  0 "register_operand" "=v")
-	(fix:SI (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fdtosi.rz\t%0, %1")
-
-;; unsigned SI <- SF
-(define_insn "fixuns_truncsfsi2"
-  [(set (match_operand:SI		   0 "register_operand" "=v")
-	(unsigned_fix:SI (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fstoui.rz\t%0, %1")
-
-;; unsigned SI <- DF
-(define_insn "fixuns_truncdfsi2"
-  [(set (match_operand:SI		   0 "register_operand" "=v")
-	(unsigned_fix:SI (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fdtoui.rz\t%0, %1")
+  DONE;
 
+}")
 
 ;; -------------------------------------------------------------------------
-;; Float mov instructions
+;; Instructions for float cstore
 ;; -------------------------------------------------------------------------
 
-;; Note:  movsf and movdf patterns are in csky.md.
-
-;; cstore SF
-(define_expand "cstoresf4"
+(define_expand "cstore<mode>4"
   [(set (match_operand:SI 0 "register_operand" "")
-	(match_operator	  1 "ordered_comparison_operator"
-	  [(match_operand:SF 2 "register_operand" "")
-	   (match_operand:SF 3 "csky_compare_operand_float" "")]))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "
-  {
-    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
-					   operands[2], operands[3]);
-    if (invert)
+	(match_operator   1 "csky_float_comparison_operator"
+	  [(match_operand:SFDF 2 "register_operand" "")
+	   (match_operand:SFDF 3 "csky_compare_operand_float" "")]))]
+  "CSKY_ISA_FEATURE (fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "{
+    bool invert;
+
+    invert = csky_emit_compare_float (GET_CODE (operands[1]),
+				 operands[2], operands[3]);
+    if(invert)
       emit_insn (gen_mvcv (operands[0]));
     else
       emit_insn (gen_mvc (operands[0]));
@@ -547,21 +333,91 @@
   }"
 )
 
-;; cstore DF
-(define_expand "cstoredf4"
+(define_expand "cstorehf4"
   [(set (match_operand:SI 0 "register_operand" "")
-	(match_operator 1 "ordered_comparison_operator"
-	  [(match_operand:DF 2 "register_operand" "")
-	   (match_operand:DF 3 "csky_compare_operand_float" "")]))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "
-  {
-    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
-					   operands[2], operands[3]);
-    if (invert)
+	(match_operator   1 "csky_float_comparison_operator"
+	  [(match_operand:HF 2 "register_operand" "")
+	   (match_operand:HF 3 "csky_compare_operand_float" "")]))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "{
+    bool invert;
+
+    invert = csky_emit_compare_float (GET_CODE (operands[1]),
+				 operands[2], operands[3]);
+    if(invert)
       emit_insn (gen_mvcv (operands[0]));
     else
       emit_insn (gen_mvc (operands[0]));
     DONE;
   }"
 )
+
+;; -------------------------------------------------------------------------
+;; Float convert instructions
+;; -------------------------------------------------------------------------
+
+;; SF <- HF
+(define_expand "extendhfsf2"
+  [(set (match_operand:SF		  0 "register_operand" "")
+	(float_extend:SF (match_operand:HF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; HF <- SF
+(define_expand "truncsfhf2"
+  [(set (match_operand:HF		     0 "register_operand" "")
+	(float_truncate:HF (match_operand:SF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; DF <- SF
+(define_expand "extendsfdf2"
+  [(set (match_operand:DF		  0 "register_operand" "")
+	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
+  "")
+
+;; SF <- DF
+(define_expand "truncdfsf2"
+  [(set (match_operand:SF		    0 "register_operand" "")
+	(float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
+  "")
+
+;; HF <- unsigned SI,SI
+(define_expand "float<floatsuop>sihf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(FLOAT_SU:HF (match_operand:SI 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; DF,SF <- unsigned SI,SI
+(define_expand "float<floatsuop>si<mode>2"
+  [(set (match_operand:SFDF		    0 "register_operand" "")
+	(FLOAT_SU:SFDF (match_operand:SI 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
+
+;; HF <- unsigned HI,HI
+(define_expand "float<floatsuop>hihf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(FLOAT_SU:HF (match_operand:HI 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; unsigned SI,SI <- HF
+(define_expand "fix<fixsuop>_trunchfsi2"
+  [(set (match_operand:SI	    0 "register_operand" "")
+	(FIX_SU:SI (fix:HF (match_operand:HF 1 "register_operand" ""))))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; unsigned SI,SI <- DF,SF
+(define_expand "fix<fixsuop>_trunc<mode>si2"
+  [(set (match_operand:SI	    0 "register_operand" "")
+	(FIX_SU:SI (fix:SFDF (match_operand:SFDF 1 "register_operand" ""))))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
+
+(include "csky_insn_fpuv3.md")
+(include "csky_insn_fpuv2.md")
diff --git a/gcc/config/csky/csky_insn_fpuv2.md b/gcc/config/csky/csky_insn_fpuv2.md
new file mode 100644
index 0000000..0a680f8
--- /dev/null
+++ b/gcc/config/csky/csky_insn_fpuv2.md
@@ -0,0 +1,470 @@
+
+;; -------------------------------------------------------------------------
+;; Float Abs instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_abssf2"
+  [(set (match_operand:SF	 0 "register_operand" "=v,a,r")
+	(abs:SF (match_operand:SF 1 "register_operand" "v, 0,r")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "@
+    fabss\t%0, %1
+    bclri\t%0, %1, 31
+    bclri\t%0, %1, 31"
+  [(set_attr "length" "4,2,4")])
+
+(define_insn "*fpuv2_absdf2"
+  [(set (match_operand:DF	 0 "register_operand" "=v")
+	(abs:DF (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fabsd\t%0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Float Neg instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_negsf2"
+  [(set (match_operand:SF	 0 "register_operand" "=v")
+	(neg:SF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnegs\t%0, %1")
+
+(define_insn "*fpuv2_negdf2"
+  [(set (match_operand:DF	 0 "register_operand" "=v")
+	(neg:DF (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnegd\t%0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Float Sqrt instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_sqrtsf2"
+  [(set (match_operand:SF	  0 "register_operand" "=v")
+	(sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fsqrts\t%0, %1")
+
+(define_insn "*fpuv2_sqrtdf2"
+  [(set (match_operand:DF	  0 "register_operand" "=v")
+	(sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_divd)"
+ "fsqrtd\t%0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Float Add instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_addsf3"
+  [(set (match_operand:SF	  0 "register_operand" "=v")
+	(plus:SF (match_operand:SF 1 "register_operand" "v")
+		 (match_operand:SF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fadds\t%0, %1, %2")
+
+(define_insn "*fpuv2_adddf3"
+  [(set (match_operand:DF	  0 "register_operand" "=v")
+	(plus:DF (match_operand:DF 1 "register_operand" "v")
+		 (match_operand:DF 2 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_df)"
+ "faddd\t%0, %1, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float Sub instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_subsf3"
+  [(set (match_operand:SF	   0 "register_operand" "=v")
+	(minus:SF (match_operand:SF 1 "register_operand" "v")
+		  (match_operand:SF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fsubs\t%0, %1, %2")
+
+(define_insn "*fpuv2_subdf3"
+  [(set (match_operand:DF	   0 "register_operand" "=v")
+	(minus:DF (match_operand:DF 1 "register_operand" "v")
+		  (match_operand:DF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fsubd\t%0, %1, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float Mul instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv2_mulsf3"
+  [(set (match_operand:SF	  0 "register_operand" "=v")
+	(mult:SF (match_operand:SF 1 "register_operand" "v")
+		 (match_operand:SF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fmuls\t%0, %1, %2")
+
+(define_insn "*fpv2_muldf3"
+  [(set (match_operand:DF	  0 "register_operand" "=v")
+	(mult:DF (match_operand:DF 1 "register_operand" "v")
+		 (match_operand:DF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fmuld\t%0, %1, %2")
+
+(define_insn "*fpuv2_nmulsf3_1"
+  [(set (match_operand:SF		  0 "register_operand" "=v")
+	(mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
+		 (match_operand:SF	 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
+  "fnmuls\t%0, %1, %2")
+
+(define_insn "*fpuv2_nmulsf3_2"
+  [(set (match_operand:SF		  0 "register_operand" "=v")
+	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
+			 (match_operand:SF 2 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnmuls\t%0, %1, %2")
+
+(define_insn "*fpuv2_nmuldf3_1"
+  [(set (match_operand:DF		  0 "register_operand" "=v")
+	(mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
+		 (match_operand:DF	 2 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
+ "fnmuld\t%0, %1, %2")
+
+(define_insn "*fpuv2_nmuldf3_2"
+  [(set (match_operand:DF		  0 "register_operand" "=v")
+	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
+			 (match_operand:DF 2 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnmuld\t%0, %1, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float Div instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_divsf3"
+  [(set (match_operand:SF	 0 "register_operand" "=v")
+	(div:SF (match_operand:SF 1 "register_operand" "v")
+		(match_operand:SF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fdivs\t%0, %1, %2")
+
+(define_insn "*fpuv2_1_divsf3"
+  [(set (match_operand:SF	 0 "register_operand"	  "=v")
+	(div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
+		(match_operand:SF 2 "register_operand"	  "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "frecips\t%0, %2")
+
+(define_insn "*fpuv2_divdf3"
+  [(set (match_operand:DF	 0 "register_operand" "=v")
+	(div:DF (match_operand:DF 1 "register_operand" "v")
+		(match_operand:DF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_divd)"
+  "fdivd\t%0, %1, %2")
+
+(define_insn "*fpuv2_1_divdf3"
+  [(set (match_operand:DF	 0 "register_operand"	  "=v")
+	(div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
+		(match_operand:DF 2 "register_operand"	  "v")))]
+  "CSKY_ISA_FEATURE (fpv2_divd)"
+  "frecipd\t%0, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float add(sub) with mult instructions
+;; -------------------------------------------------------------------------
+
+;; vrz <= vrz + vrx * vry
+(define_insn "*fpuv2_fmacs"
+  [(set (match_operand:SF		   0 "register_operand" "=v")
+	(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
+			  (match_operand:SF 2 "register_operand" "v"))
+		 (match_operand:SF	  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fmacs\t%0, %1, %2")
+
+(define_insn "*fpuv2_fmacd"
+  [(set (match_operand:DF		   0 "register_operand" "=v")
+	(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
+			  (match_operand:DF 2 "register_operand" "v"))
+		 (match_operand:DF	  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fmacd\t%0, %1, %2")
+
+;; vrz <= vrz - vrx * vry
+(define_insn "*fpuv2_fnmacs"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(minus:SF (match_operand:SF	  1 "register_operand" "0")
+		  (mult:SF (match_operand:SF 2 "register_operand" "v")
+			   (match_operand:SF 3 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnmacs\t%0, %2, %3")
+
+(define_insn "*fpuv2_fnmacd"
+  [(set (match_operand:DF		    0 "register_operand" "=v")
+	(minus:DF (match_operand:DF	  1 "register_operand" "0")
+		  (mult:DF (match_operand:DF 2 "register_operand" "v")
+			   (match_operand:DF 3 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnmacd\t%0, %2, %3")
+
+;; vrz <= vrx * vry - vrz
+(define_insn "*fpuv2_fmscs"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
+			   (match_operand:SF 2 "register_operand" "v"))
+		  (match_operand:SF	  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fmscs\t%0, %1, %2")
+
+(define_insn "*fpuv2_fmscd"
+  [(set (match_operand:DF 0 "register_operand" "=v")
+	(minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
+			   (match_operand:DF 2 "register_operand" "v"))
+		  (match_operand:DF 3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fmscd\t%0, %1, %2")
+
+;; vrz = - (vrz + vrx * vry)
+(define_insn "*fpuv2_fnmscs_1"
+  [(set (match_operand:SF			    0 "register_operand" "=v")
+	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
+			   (match_operand:SF	 2 "register_operand" "v"))
+		  (match_operand:SF		  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnmscs\t%0, %1, %2")
+
+(define_insn "*fpuv2_fnmscs_2"
+  [(set (match_operand:SF			   0 "register_operand" "=v")
+	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
+				  (match_operand:SF 2 "register_operand" "v"))
+			 (match_operand:SF	  3 "register_operand" "0"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnmscs\t%0, %1, %2")
+
+(define_insn "*fpuv2_fnmscd_1"
+  [(set (match_operand:DF 0 "register_operand" "=v")
+	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
+			   (match_operand:DF 2 "register_operand" "v"))
+		  (match_operand:DF 3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnmscd\t%0, %1, %2")
+
+(define_insn "*fpuv2_fnmscd_2"
+  [(set (match_operand:DF 0 "register_operand" "=v")
+	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
+				  (match_operand:DF 2 "register_operand" "v"))
+			 (match_operand:DF 3 "register_operand" "0"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnmscd\t%0, %1, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float compare instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_unordered"
+  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
+				  (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpuos\t%0, %1")
+
+(define_insn "*fpuv2_unordered_zero"
+  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
+				  (match_operand:SF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpuos\t%0, %0")
+
+(define_insn "*fpuv2_ne"
+  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpnes\t%0, %1")
+
+(define_insn "*fpuv2_gt"
+  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmplts\t%1, %0")
+
+(define_insn "*fpuv2_ge"
+  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_sf)"
+ "fcmphss\t%0, %1")
+
+(define_insn "*fpuv2_lt"
+  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmplts\t%0, %1")
+
+(define_insn "*fpuv2_le"
+  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_sf)"
+ "fcmphss\t%1, %0")
+
+(define_insn "*fpuv2_gez"
+  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand"	  "v")
+			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpzhss\t%0")
+
+(define_insn "*fpuv2_nez"
+  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand"	  "v")
+			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpznes\t%0")
+
+(define_insn "*fpuv2_dunordered"
+  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
+				  (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpuod\t%0, %1")
+
+(define_insn "*fpuv2_dunordered_zero"
+  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
+				  (match_operand:DF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpuod\t%0, %0")
+
+(define_insn "*fpuv2_dne"
+  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpned\t%0, %1")
+
+(define_insn "*fpuv2_dgt"
+  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpltd\t%1, %0")
+
+(define_insn "*fpuv2_dge"
+  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmphsd\t%0, %1")
+
+(define_insn "*fpuv2_dlt"
+  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_df)"
+ "fcmpltd\t%0, %1")
+
+(define_insn "*fpuv2_dle"
+  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmphsd\t%1, %0")
+
+(define_insn "*fpuv2_dgez"
+  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand"	  "v")
+			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
+ "CSKY_ISA_FEATURE (fpv2_df)"
+ "fcmpzhsd\t%0")
+
+(define_insn "*fpuv2_dnez"
+  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand"	  "v")
+			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpzned\t%0")
+
+
+;; -------------------------------------------------------------------------
+;; Float convert instructions
+;; -------------------------------------------------------------------------
+
+;; DF <- SF
+(define_insn "*fpuv2_extendsfdf2"
+  [(set (match_operand:DF		  0 "register_operand" "=v")
+	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fstod\t%0, %1")
+
+;; SF <- DF
+(define_insn "*fpuv2_truncdfsf2"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fdtos\t%0, %1")
+
+;; SF <- SI
+(define_insn "*fpuv2_floatsisf2"
+  [(set (match_operand:SF	   0 "register_operand" "=v")
+	(float:SF (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fsitos\t%0, %1")
+
+;; DF <- SI
+(define_insn "*fpuv2_floatsidf2"
+  [(set (match_operand:DF	   0 "register_operand" "=v")
+	(float:DF (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fsitod\t%0, %1")
+
+;; SF <- unsigned SI
+(define_insn "*fpuv2_floatunssisf2"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fuitos\t%0, %1")
+
+;; DF <- unsigned SI
+(define_insn "*fpuv2_floatunssidf2"
+  [(set (match_operand:DF		    0 "register_operand" "=v")
+	(unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fuitod\t%0, %1")
+
+;; SI <- SF
+(define_insn "*fpuv2_fix_truncsfsi2"
+  [(set (match_operand:SI	 0 "register_operand" "=v")
+	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fstosi.rz\t%0, %1")
+
+;; SI <- DF
+(define_insn "*fpuv2_fix_truncdfsi2"
+  [(set (match_operand:SI	 0 "register_operand" "=v")
+	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fdtosi.rz\t%0, %1")
+
+;; unsigned SI <- SF
+(define_insn "*fpuv2_fixuns_truncsfsi2"
+  [(set (match_operand:SI		  0 "register_operand" "=v")
+	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fstoui.rz\t%0, %1")
+
+;; unsigned SI <- DF
+(define_insn "*fpuv2_fixuns_truncdfsi2"
+  [(set (match_operand:SI		  0 "register_operand" "=v")
+	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fdtoui.rz\t%0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Float mov instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r, r,m,v,r,Q,v,v,v")
+	(match_operand:SF 1 "general_operand"      " r,m,mF,r,r,v,v,Q,v,W"))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "* return csky_output_move(insn, operands, SFmode);"
+)
+
+(define_insn "*fpuv2_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, r,m, v,?r,Q,v,v,v")
+	(match_operand:DF 1 "general_operand"      " r,m,mF,r,?r, v,v,Q,v,m"))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "* return csky_output_movedouble(operands, DFmode);"
+  [(set (attr "length")
+	(symbol_ref "csky_get_movedouble_length (operands)"))]
+)
diff --git a/gcc/config/csky/csky_insn_fpuv3.md b/gcc/config/csky/csky_insn_fpuv3.md
new file mode 100644
index 0000000..053673c
--- /dev/null
+++ b/gcc/config/csky/csky_insn_fpuv3.md
@@ -0,0 +1,497 @@
+
+(define_c_enum "unspec" [
+  UNSPEC_MAXNM_F3
+  UNSPEC_MINNM_F3
+])
+
+;; -------------------------------------------------------------------------
+;; Float mov instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_movhf"
+  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v, v")
+	(match_operand:HF 1 "general_operand"      " r,F,r,v,r,m,v,Q,v,W,Dv"))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "*
+  switch (which_alternative)
+    {
+    case 2:
+      return \"fmtvr.16\\t%0, %1\";
+    case 3:
+      return \"fmfvr.16\\t%0, %1\";
+    case 6:
+    case 7:
+    case 9:
+      return fpuv3_output_move(operands);
+    case 8:
+      return \"fmov.16\\t%0, %1\";
+    case 10:
+      return \"fmovi.16\\t%0, %1\";
+    case 1:
+      {
+	long bits;
+	rtx ops[4];
+
+	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), HFmode);
+	ops[0] = operands[0];
+	ops[1] = GEN_INT (bits);
+
+	output_asm_insn (\"lrw\\t%0, %1\", ops);
+	return \"\";
+      }
+    default:
+      return csky_output_move(insn, operands, HFmode);
+    }
+  "
+)
+
+(define_insn "*fpv3_movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r, r,m,v,r,Q,v,v,v, v")
+	(match_operand:SF 1 "general_operand"      " r,m,mF,r,r,v,v,Q,v,W,Dv"))]
+  "CSKY_ISA_FEATURE(fpv3_sf)"
+  "*
+  switch (which_alternative)
+    {
+    case 4:
+      return \"fmtvr.32.1\\t%0, %1\";
+    case 5:
+      return \"fmfvr.32.1\\t%0, %1\";
+    case 6:
+    case 7:
+    case 9:
+      return fpuv3_output_move(operands);
+    case 8:
+      return \"fmov.32\\t%0, %1\";
+    case 10:
+      return \"fmovi.32\\t%0, %1\";
+    default:
+      return csky_output_move(insn, operands, SFmode);
+    }
+  "
+)
+
+(define_insn "*fpv3_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, r,m,v,?r,Q,v,v,v, v")
+	(match_operand:DF 1 "general_operand"      " r,m,mF,r,?r,v,v,Q,v,m,Dv"))]
+  "CSKY_ISA_FEATURE(fpv3_df)"
+  "*
+  switch (which_alternative)
+    {
+    case 4:
+      if (TARGET_BIG_ENDIAN)
+	return \"fmtvr.64\\t%0, %R1, %1\";
+      return \"fmtvr.64\\t%0, %1, %R1\";
+    case 5:
+      if (TARGET_BIG_ENDIAN)
+	return \"fmfvr.64\\t%R0, %0, %1\";
+      return \"fmfvr.64\\t%0, %R0, %1\";
+    case 6:
+    case 7:
+    case 9:
+      return fpuv3_output_move(operands);
+    case 8:
+      return \"fmov.64\\t%0, %1\";
+    case 10:
+      return \"fmovi.64\\t%0, %1\";
+    default:
+      return csky_output_movedouble(operands, DFmode);
+    }
+  "
+)
+
+;; -------------------------------------------------------------------------
+;; Float Mul instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_mul<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+		    (match_operand:F3ANY  2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fmul.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float Muladd and mulsub instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_mula<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "+v")
+	(plus:F3ANY (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+				(match_operand:F3ANY  2 "register_operand" " v"))
+		    (match_dup 0)))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_muls<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "+v")
+	(minus:F3ANY (match_dup 0)
+		     (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+				 (match_operand:F3ANY  2 "register_operand" " v"))))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fmuls.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float fmula/fmuls/fnmula/fnmuls instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_fmuls_<mode>4"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(fma:F3ANY (neg:F3ANY (match_operand:F3ANY  1 "register_operand" "v"))
+		   (match_operand:F3ANY   2 "register_operand" "v")
+		   (match_operand:F3ANY   3 "register_operand"  "0")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "ffmuls.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fmula_<mode>4"
+  [(set (match_operand:F3ANY	    0 "register_operand" "=v")
+	(fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+		   (match_operand:F3ANY 2 "register_operand" " v")
+		   (match_operand:F3ANY 3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "ffmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fnmula_<mode>4"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(neg: F3ANY (fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+			       (match_operand:F3ANY  2 "register_operand" " v")
+			       (match_operand:F3ANY  3 "register_operand" "0"))))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "ffnmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fnmuls_<mode>4"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+		   (match_operand:F3ANY  2 "register_operand" " v")
+		   (neg:F3ANY (match_operand:F3ANY  3 "register_operand" "0"))))]
+  "CSKY_ISA_FEATURE(fpv3_sf)"
+  "ffnmuls.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float div/recipe/sqrt instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_div<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(div:F3ANY (match_operand:F3ANY   1 "register_operand" " v")
+		   (match_operand:F3ANY   2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fdiv.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_recip<mode>3"
+  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
+	(div:F3ANY (match_operand:F3ANY  1 "csky_const_float1_operand" " i")
+		   (match_operand:F3ANY  2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "frecip.<f3t>\t%0, %2"
+)
+
+(define_insn "*fpv3_sqrt<mode>2"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(sqrt:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fsqrt.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float fmax/fmin instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "fmax<mode>3"
+  [(set (match_operand:F3ANY		 0 "register_operand" "=v")
+	(unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
+		       (match_operand:F3ANY  2 "register_operand" " v")]
+		      UNSPEC_MAXNM_F3))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fmaxnm.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "fmin<mode>3"
+  [(set (match_operand:F3ANY		 0 "register_operand" "=v")
+	(unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
+		       (match_operand:F3ANY  2 "register_operand" " v")]
+		      UNSPEC_MINNM_F3))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fminnm.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float compare instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_<zero_inst>_<mode>3"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(FCMPZ:CC (match_operand:F3ANY 0 "register_operand" "v")
+		  (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
+   "CSKY_ISA_FEATURE(fpv3_<mode>)"
+   "fcmp<zero_inst>.<f3t>\t%0"
+)
+
+(define_insn "*fpv3_<reg_inst>_<mode>3"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(FCMP:CC (match_operand:F3ANY 0 "register_operand" "v")
+		 (match_operand:F3ANY 1 "register_operand" "v")))]
+   "CSKY_ISA_FEATURE(fpv3_<mode>)"
+   "fcmp<reg_inst>.<f3t>\t%0, %1"
+)
+
+(define_insn "*fpv3_gt<mode>3"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(gt:CC (match_operand:F3ANY 0 "register_operand" "v")
+	       (match_operand:F3ANY 1 "register_operand" "v")))]
+   "CSKY_ISA_FEATURE(fpv3_<mode>)"
+   "fcmplt.<f3t>\t%1, %0"
+)
+
+(define_insn "*fpv3_le<mode>3"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(le:CC (match_operand:F3ANY 0 "register_operand" "v")
+	       (match_operand:F3ANY 1 "register_operand" "v")))]
+   "CSKY_ISA_FEATURE(fpv3_<mode>)"
+   "fcmphs.<f3t>\t%1, %0"
+)
+
+(define_insn "*fpv3_unordered"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
+		      (match_operand:F3ANY 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fcmpuo.<f3t>\t%0, %1")
+
+(define_insn "*fpv3_unordered_zero"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
+		      (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fcmpuoz.<f3t>\t%0")
+
+;; -------------------------------------------------------------------------
+;; Float ADD instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_add<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(plus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+		    (match_operand:F3ANY  2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fadd.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float SUB instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_sub<mode>3"
+  [(set (match_operand:F3ANY	       0 "register_operand" "=v")
+	(minus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+		     (match_operand:F3ANY  2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fsub.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float NEG instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_neg<mode>2"
+  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
+	(neg:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fneg.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float ABS instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_abs<mode>2"
+  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
+	(abs:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fabs.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float common convert instructions
+;; -------------------------------------------------------------------------
+
+;; SF <- HF
+(define_insn "*fpv3_extendhfsf2"
+  [(set (match_operand:SF		  0 "register_operand" "=v")
+	(float_extend:SF (match_operand:HF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "fhtos\t%0, %1")
+
+;; HF <- SF
+(define_insn "*fpv3_truncsfhf2"
+  [(set (match_operand:HF		     0 "register_operand" "=v")
+	(float_truncate:HF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "fstoh\t%0, %1")
+
+;; DF <- SF
+(define_insn "*fpv3_extendsfdf2"
+  [(set (match_operand:DF		  0 "register_operand" "=v")
+	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_df)"
+  "fstod\t%0, %1")
+
+;; SF <- DF
+(define_insn "*fpv3_truncdfsf2"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_df)"
+  "fdtos\t%0, %1")
+
+;; DF,SF,HF <- unsigned SI,SI
+(define_insn "*fpv3_float<floatsuop>si<mode>2"
+  [(set (match_operand:F3ANY	   0 "register_operand" "=v")
+	(FLOAT_SU:F3ANY (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fitof.<floatsu>32.f<f3t>\t%0, %1")
+
+;; HF <- unsigned HI,HI
+(define_insn "*fpv3_float<floatsuop>hihf2"
+  [(set (match_operand:HF	   0 "register_operand" "=v")
+	(FLOAT_SU:HF (match_operand:HI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
+  "fitof.<floatsu>16.f16\t%0, %1")
+
+;; unsigned SI,SI <- DF,SF,HF
+(define_insn "*fpv3_fix<fixsuop>_trunc<mode>si2"
+  [(set (match_operand:SI	    0 "register_operand" "=v")
+	(FIX_SU:SI (fix:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fftoi.f<f3t>.<fixsu>32.rz\t%0, %1")
+
+;; -------------------------------------------------------------------------
+;; Float complex convert instructions
+;; -------------------------------------------------------------------------
+
+;; Fixed point to floating point conversions.
+
+;(define_insn "*combine_fcvt_fixed16_<mode>"
+;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
+;	(mult:F3ANY (float:F3ANY (match_operand:HI 1 "register_operand" "0"))
+;	       (match_operand 2
+;			"const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
+;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
+;   && CSKY_ISA_FEATURE(fpv3_hi)"
+;  "fxtof.s16.f<f3t>\t%0, %1, %v2")
+;
+;(define_insn "*combine_fcvt_fixed32_<mode>"
+;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
+;	(mult:F3ANY (float:F3ANY (match_operand:SI 1 "register_operand" "0"))
+;	       (match_operand 2
+;			"const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
+;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
+;  "fxtof.s32.f<f3t>\t%0, %1, %v2")
+;
+;(define_insn "*combine_fcvt_unfixed16_<mode>"
+;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
+;	(mult:F3ANY (unsigned_float:F3ANY (match_operand:HI 1 "register_operand" "0"))
+;	       (match_operand 2
+;			"const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
+;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
+;   && CSKY_ISA_FEATURE(fpv3_hi)"
+;  "fxtof.u16.f<f3t>\t%0, %1, %v2")
+;
+;(define_insn "*combine_fcvt_unfixed32_<mode>"
+;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
+;	(mult:F3ANY (unsigned_float:F3ANY (match_operand:SI 1 "register_operand" "0"))
+;	       (match_operand 2
+;			"const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
+;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
+;  "fxtof.u32.f<f3t>\t%0, %1, %v2")
+
+;; Floating point to fixed point conversions.
+
+;(define_insn "*combine_fcvt<mode>_fixed16"
+;  [(set (match_operand:HI 0 "register_operand" "=v")
+;	(fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
+;			    (match_operand 2
+;			     "const_double_fcvt_power_of_two_hq" "Du")))))]
+;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
+;   && CSKY_ISA_FEATURE(fpv3_hi)"
+;  "fftox.f<f3t>.s16\t%0, %1, %v2"
+; )
+;
+;(define_insn "*combine_fcvt<mode>_fixed32"
+;  [(set (match_operand:SI 0 "register_operand" "=v")
+;	(fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
+;			    (match_operand 2
+;			     "const_double_fcvt_power_of_two_sq" "Du")))))]
+;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
+;  "fftox.f<f3t>.s32\t%0, %1, %v2"
+; )
+;
+;(define_insn "*combine_fcvt<mode>_unfixed16"
+;  [(set (match_operand:HI 0 "register_operand" "=v")
+;	(unsigned_fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
+;				     (match_operand 2
+;				      "const_double_fcvt_power_of_two_hq" "Du")))))]
+;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
+;   && CSKY_ISA_FEATURE(fpv3_hi)"
+;  "fftox.f<f3t>.u16\t%0, %1, %v2"
+; )
+;
+;(define_insn "*combine_fcvt<mode>_unfixed32"
+;  [(set (match_operand:SI 0 "register_operand" "=v")
+;	(unsigned_fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
+;				     (match_operand 2
+;				      "const_double_fcvt_power_of_two_sq" "Du")))))]
+;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
+;  "fftox.f<f3t>.u32\t%0, %1, %v2"
+; )
+
+;; conversions need to be rounding to nearest.
+
+(define_insn "l<frm_pattern><fixsuop><mode>si2"
+  [(set (match_operand:SI 0 "register_operand" "=v")
+	(FIX_SU:SI (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")]
+				   FRM)))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fftoi.f<f3t>.<fixsu>32<rm>\t%0, %1"
+)
+
+(define_insn "<frm_pattern><mode>2"
+  [(set (match_operand:F3ANY 0 "register_operand" "=v")
+	(unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")] FRMF))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fftofi.f<f3t><rm>\t%0, %1"
+)
+
+;; Write Floating-point Control Register.
+(define_insn "csky_setfcrsi"
+  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FCR)]
+  "CSKY_ISA_FEATURE(fcr)"
+  "mtcr\t%0, fcr"
+)
+
+;; Read Floating-point Control Register.
+(define_insn "csky_getfcrsi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FCR))]
+  "CSKY_ISA_FEATURE(fcr)"
+  "mfcr\t%0, fcr"
+)
+
+;; Insert Floating-point Control Register.
+(define_insn "csky_insfcrsi"
+  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
+		     (match_operand:SI 1 "const_int_operand" "i")
+		     (match_operand:SI 2 "const_int_operand" "i")]VUNSPEC_INS_FCR)
+   (clobber (reg: SI 13))]
+  "CSKY_ISA_FEATURE(fcr)"
+  {
+    operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1);
+    return "mfcr\tt1, fcr\n\tins\tt1, %0, %1, %2\n\tmtcr\tt1, fcr";
+  }
+)
diff --git a/gcc/config/csky/csky_isa.def b/gcc/config/csky/csky_isa.def
index 5edce16..5849819 100644
--- a/gcc/config/csky/csky_isa.def
+++ b/gcc/config/csky/csky_isa.def
@@ -32,6 +32,7 @@ CSKY_ISA (7E10,	 "Extended insns for arch ck810	 from ck807")
 
 /* Special insns */
 CSKY_ISA (div,	  "divide insns")
+CSKY_ISA (fcr,	  "Control the fcr register")
 
 /* Extended insns */
 CSKY_ISA (dsp,	 "Extended insns for DSP")
@@ -41,6 +42,11 @@ CSKY_ISA (fpv2_sf,    "Single precision operations supported")
 CSKY_ISA (fpv2_df,    "Double precision operations supported")
 CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
 
+CSKY_ISA (fpv3_hi,    "half word for fpu convert supported")
+CSKY_ISA (fpv3_hf,    "half precision operations supported")
+CSKY_ISA (fpv3_sf,    "Single precision operations supported")
+CSKY_ISA (fpv3_df,    "Double precision operations supported")
+
 /* Specific insns mode */
 #ifdef	CSKY_ISA_MACRO
 #define CSKY_ISA_CK801	    CSKY_ISA_FEATURE_GET (E1)
@@ -50,10 +56,19 @@ CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
 #define CSKY_ISA_CK803R1    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E3r1)
 #define CSKY_ISA_CK807	    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E7)
 #define CSKY_ISA_CK810	    CSKY_ISA_CK807, CSKY_ISA_FEATURE_GET (7E10)
+#define CSKY_ISA_CK860      CSKY_ISA_CK810, CSKY_ISA_FEATURE_GET(3E3r1)
 
 #define CSKY_ISA_DSP	    CSKY_ISA_FEATURE_GET (dsp)
 
 #define CSKY_ISA_FPv2_SF    CSKY_ISA_FEATURE_GET (fpv2_sf)
 #define CSKY_ISA_FPv2	    CSKY_ISA_FPv2_SF, CSKY_ISA_FEATURE_GET (fpv2_df)
 #define CSKY_ISA_FPv2_DIVD  CSKY_ISA_FPv2, CSKY_ISA_FEATURE_GET (fpv2_divd)
+
+#define CSKY_ISA_FPv3_HF    CSKY_ISA_FEATURE_GET (fpv3_hf), \
+                            CSKY_ISA_FEATURE_GET (fpv3_hi)
+#define CSKY_ISA_FPv3_HSF   CSKY_ISA_FPv3_HF, \
+                            CSKY_ISA_FEATURE_GET (fpv3_sf)
+#define CSKY_ISA_FPv3_SDF   CSKY_ISA_FEATURE_GET (fpv3_sf), \
+                            CSKY_ISA_FEATURE_GET (fpv3_df)
+#define CSKY_ISA_FPv3       CSKY_ISA_FPv3_HF, CSKY_ISA_FPv3_SDF
 #endif
diff --git a/gcc/config/csky/csky_tables.opt b/gcc/config/csky/csky_tables.opt
index 3501f90..ca113dd 100644
--- a/gcc/config/csky/csky_tables.opt
+++ b/gcc/config/csky/csky_tables.opt
@@ -194,6 +194,12 @@ Enum(csky_processor_type) String(ck810ft) Value( TARGET_CPU_ck810ff)
 EnumValue
 Enum(csky_processor_type) String(ck810ftv) Value( TARGET_CPU_ck810ftv)
 
+EnumValue
+Enum(csky_processor_type) String(ck860) Value( TARGET_CPU_ck860)
+
+EnumValue
+Enum(csky_processor_type) String(ck860f) Value( TARGET_CPU_ck860f)
+
 Enum
 Name(csky_arch) Type(int)
 Known CSKY architectures (for use with the -march= option):
@@ -213,6 +219,9 @@ Enum(csky_arch) String(ck807) Value(3)
 EnumValue
 Enum(csky_arch) String(ck810) Value(4)
 
+EnumValue
+Enum(csky_arch) String(ck860) Value(5)
+
 Enum
 Name(csky_fpu) Type(enum csky_fpu_type)
 Known CSKY FPUs (for use with the -mfpu= option):
@@ -227,4 +236,16 @@ EnumValue
 Enum(csky_fpu) String(fpv2_divd) Value(TARGET_FPU_fpv2_divd)
 
 EnumValue
+Enum(csky_fpu) String(fpv3_hf) Value(TARGET_FPU_fpv3_hf)
+
+EnumValue
+Enum(csky_fpu) String(fpv3_hsf) Value(TARGET_FPU_fpv3_hsf)
+
+EnumValue
+Enum(csky_fpu) String(fpv3_sdf) Value(TARGET_FPU_fpv3_sdf)
+
+EnumValue
+Enum(csky_fpu) String(fpv3) Value(TARGET_FPU_fpv3)
+
+EnumValue
 Enum(csky_fpu) String(auto) Value(TARGET_FPU_auto)
diff --git a/gcc/config/csky/predicates.md b/gcc/config/csky/predicates.md
index 4ffecb0..878446d 100644
--- a/gcc/config/csky/predicates.md
+++ b/gcc/config/csky/predicates.md
@@ -294,5 +294,4 @@
 })
 
 (define_special_predicate "csky_float_comparison_operator"
-  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
-	       unordered,ordered"))
+  (match_code "eq,ne,le,lt,ge,gt,unordered,ordered"))
diff --git a/gcc/config/csky/t-csky-elf b/gcc/config/csky/t-csky-elf
index bbdf286..4e7fcbe 100644
--- a/gcc/config/csky/t-csky-elf
+++ b/gcc/config/csky/t-csky-elf
@@ -27,8 +27,8 @@ MULTILIB_MATCHES      = mbig-endian=EB
 MULTILIB_EXCEPTIONS   =
 
 # Arch variants.
-MULTILIB_OPTIONS     += mcpu=ck802/mcpu=ck801/mcpu=ck803f/mcpu=ck807f/mcpu=ck810f
-MULTILIB_DIRNAMES    += ck802 ck801 ck803 ck807 ck810
+MULTILIB_OPTIONS     += mcpu=ck802/mcpu=ck801/mcpu=ck803f/mcpu=ck807f/mcpu=ck810f/mcpu=ck860f
+MULTILIB_DIRNAMES    += ck802 ck801 ck803 ck807 ck810 ck860
 
 # For arch ck802.
 MULTILIB_MATCHES     += mcpu?ck802=march?ck802
@@ -100,6 +100,11 @@ MULTILIB_MATCHES     += mcpu?ck807f=march?ck807ef
 MULTILIB_MATCHES     += mcpu?ck807f=march?ck807
 MULTILIB_MATCHES     += mcpu?ck807f=mcpu?ck807
 
+# For arch ck860
+MULTILIB_MATCHES     += mcpu?ck860f=march?ck860
+MULTILIB_MATCHES     += mcpu?ck860f=mcpu?ck860
+MULTILIB_MATCHES     += mcpu?ck860f=mcpu?c860
+
 # For option -mfloat-abi=
 MULTILIB_OPTIONS     += mfloat-abi=soft/mfloat-abi=softfp/mfloat-abi=hard
 MULTILIB_DIRNAMES    += soft soft-fp hard-fp
diff --git a/gcc/config/csky/t-csky-linux b/gcc/config/csky/t-csky-linux
index 9435b7a..0730c3a 100644
--- a/gcc/config/csky/t-csky-linux
+++ b/gcc/config/csky/t-csky-linux
@@ -21,11 +21,11 @@
 
 
 MULTILIB_EXCEPTIONS  =
-CSKY_MULTILIB_OSDIRNAMES = mfloat-abi.softfp=/soft-fp mfloat-abi.hard=/hard-fp mfloat-abi.soft=/. mcpu.ck810f=/. mcpu.ck807f=/ck807
+CSKY_MULTILIB_OSDIRNAMES = mfloat-abi.softfp=/soft-fp mfloat-abi.hard=/hard-fp mfloat-abi.soft=/. mcpu.ck810f=/. mcpu.ck807f=/ck807 mcpu.ck860f=/ck860
 
 # Arch variants.
-MULTILIB_OPTIONS     += mcpu=ck810f/mcpu=ck807f
-MULTILIB_DIRNAMES    += ck810 ck807
+MULTILIB_OPTIONS     += mcpu=ck810f/mcpu=ck807f/mcpu=ck860f
+MULTILIB_DIRNAMES    += ck810 ck807 ck860
 
 # For ck807.
 MULTILIB_MATCHES     += mcpu?ck807f=march?ck807
@@ -41,6 +41,11 @@ MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810vf
 MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810ft
 MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810vft
 
+# For ck860
+MULTILIB_MATCHES     += mcpu?ck860f=march?ck860
+MULTILIB_MATCHES     += mcpu?ck860f=mcpu?ck860
+MULTILIB_MATCHES     += mcpu?ck860f=mcpu?c860
+
 # For option -mfloat-abi=
 MULTILIB_OPTIONS     += mfloat-abi=soft/mfloat-abi=softfp/mfloat-abi=hard
 MULTILIB_DIRNAMES    += soft soft-fp hard-fp
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index d166a0d..11b5868 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -2258,6 +2258,14 @@ Vector registers.
 
 @item z
 Stack pointer register (SP).
+
+@item Q
+A memory address which uses a base register with a short offset
+or with a index register with its scale.
+
+@item W
+A memory address which uses a base register with a index register
+with its scale.
 @end table
 
 @ifset INTERNALS
-- 
2.7.4


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] C-SKY: Add fpuv3 instructions and CK860 arch.
  2021-04-30 12:21 [PATCH] C-SKY: Add fpuv3 instructions and CK860 arch Geng Qi
@ 2021-05-24 10:49 ` Xianmiao Qu
  2021-05-24 11:32   ` Xianmiao Qu
  0 siblings, 1 reply; 5+ messages in thread
From: Xianmiao Qu @ 2021-05-24 10:49 UTC (permalink / raw)
  To: Geng Qi, gcc-patches

Hi Geng Qi,


I tested this patch but it got the following error when compiling libgcc,

during RTL pass: 
reload/lhome/quxm/build-csky-upstream/source//gcc/libgcc/libgcc2.c: In 
function 
'__mulsc3':/lhome/quxm/build-csky-upstream/source//gcc/libgcc/libgcc2.c:2010:1: 
internal compiler error: maximum number of generated reload insns per 
insn achieved 
(90)/lhome/quxm/build-csky-upstream/source//gcc/libgcc/libgcc2.c: In 
function 
'__divsc3':/lhome/quxm/build-csky-upstream/source//gcc/libgcc/libgcc2.c:2175:1: 
internal compiler error: maximum number of generated reload insns per 
insn achieved (90)

Is it related to the patches you send later? If so, please use [PATCH 
n/m] format to merge them together.


Thanks,

Xianmiao


On 4/30/21 8:21 PM, Geng Qi wrote:
> gcc/ChangeLog:
>
> 	* config/csky/constraints.md ("W"): New constriant for mem operand
> 	with base reg, index register.
> 	("Q"): Renamed and modified "csky_valid_fpuv2_mem_operand" to
> 	"csky_valid_mem_constraint_operand" to deal with both "Q" and "W"
> 	constraint.
> 	("Dv"): New constraint for const double value that can be used at
> 	fmovi instruction.
> 	* config/csky/csky-modes.def (HFmode): New mode.
> 	* config/csky/csky-protos.h (csky_valid_fpuv2_mem_operand): Rename
> 	to "csky_valid_mem_constraint_operand" and new support for constraint
> 	"W".
> 	(csky_get_movedouble_length): New.
> 	(fpuv3_output_move): New.
> 	(fpuv3_const_double): New.
> 	* config/csky/csky.c (csky_option_override): New arch CK860 with fpv3.
> 	(decompose_csky_address): Robustness adjust.
> 	(csky_print_operand): New "CONST_DOUBLE" operand.
> 	(csky_output_move): New support for fpv3 instructions.
> 	(csky_get_movedouble_length): New.
> 	(fpuv3_output_move): New.
> 	(fpuv3_const_double): New.
> 	(csky_emit_compare): New cover for float comparsion.
> 	(csky_emit_compare_float): Refine.
> 	(csky_vaild_fpuv2_mem_operand): Rename to
> 	"csky_valid_mem_constraint_operand" and new support for constraint "W".
> 	(ck860_rtx_costs): New.
> 	(csky_rtx_costs): New subcall for CK860.
> 	(regno_reg_class): New vregs for fpuv3.
> 	(csky_dbx_regno): Likewise.
> 	(csky_cpu_cpp_builtins): New builtin macro for fpuv3.
> 	(csky_conditional_register_usage): New suporrot for fpuv3.
> 	(csky_dwarf_register_span): New suporrot for fpuv3.
> 	(csky_init_builtins, csky_mangle_type): New support for "__fp16" type.
> 	(ck810_legitimate_index_p): New support for fp16.
> 	* gcc/config/csky/csky.h (TARGET_TLS): ADD CK860.
> 	(CSKY_VREG_P, CSKY_VREG_LO_P, CSKY_VREG_HI_P): New support for fpuv3.
> 	(TARGET_SINGLE_FPU): New support for fpuv3.
> 	(TARGET_SUPPORT_FPV3): New macro.
> 	(FIRST_PSEUDO_REGISTER): Value change, since the new fpuv3 regs.
> 	(FIXED_REGISTERS, CALL_REALLY_USED_REGISTERS, REGISTER_NAMES,
> 	 REG_CLASS_CONTENTS): Support for fpuv3.
> 	* gcc/config/csky/csky.md (movsf): Move to cksy_insn_fpu.md and adjust.
> 	(csky_movsf_fpv2): Likewise.
> 	(ck801_movsf): Likewise.
> 	(csky_movsf): Likewise.
> 	(movdf): Likewise.
> 	(csky_movdf_fpv2): Likewise.
> 	(ck801_movdf): Likewise.
> 	(csky_movdf): Likewise.
> 	(movsicc): Refine. Use "comparison_operatior" instead of
> 	"ordered_comparison_operatior".
> 	(addsicc): Likewise.
> 	(CSKY_FIRST_VFP3_REGNUM, CSKY_LAST_VFP3_REGNUM): New constant.
> 	(call_value_internal_vh): New insn.
> 	* config/csky/csky_cores.def (CK860): New arch and cpu.
> 	(fpv3): New 4 fpus: fpv3_hf, fpv3_hsf, fpv3_sdf and fpv3.
> 	* config/csky/csky_insn_fpu.md (mov<float_mode>): Move the float mov
> 	patterns from csky.md here.
> 	(fpuv2 instructions): Refactor. Separate all float patterns into
> 	emit-patterns and match-patterns, remain the emit-patterns here, and
> 	move the match-patterns to csky_insn_fpuv2.md.
> 	(fpuv3 instructions): Add patterns and fuse part of them with the
> 	fpuv2's.
> 	* config/csky/csky_insn_fpuv2.md: New file for fpuv2 instructions.
> 	* config/csky/csky_insn_fpuv3.md: New flie and new patterns for fpuv3
> 	isntructions.
> 	* config/csky/csky_isa.def (fcr): New.
> 	(fpv3): New 4 isa sets: fpv3_hi, fpv3_hf, fpv3_sf and fpv3_df.
> 	(CK860): New definition for ck860.
> 	* gcc/config/csky/csky_tables.opt (ck860): New processors ck860,
> 	ck860f. And new arch ck860.
> 	(fpv3): New 4 fpus: fpv3_hf, fpv3_hsf, fpv3_sdf and fpv3.
> 	* config/csky/predicates.md (csky_float_comparsion_operator): Delete
> 	"geu", "gtu", "leu", "ltu", which will never appear at float comparison.
> 	* config/cksy/t-csky-elf, config/csky/t-csky-linux: New for ck860.
> 	* doc/md.texi: Add "Q" and "W" constraints for C-SKY.
> ---
>   gcc/config/csky/constraints.md     |  13 +-
>   gcc/config/csky/csky-modes.def     |   2 +
>   gcc/config/csky/csky-protos.h      |   7 +-
>   gcc/config/csky/csky.c             | 644 ++++++++++++++++++++++++++----
>   gcc/config/csky/csky.h             | 162 ++++++--
>   gcc/config/csky/csky.md            | 127 ++----
>   gcc/config/csky/csky_cores.def     |  13 +
>   gcc/config/csky/csky_insn_fpu.md   | 798 +++++++++++++++----------------------
>   gcc/config/csky/csky_insn_fpuv2.md | 470 ++++++++++++++++++++++
>   gcc/config/csky/csky_insn_fpuv3.md | 497 +++++++++++++++++++++++
>   gcc/config/csky/csky_isa.def       |  15 +
>   gcc/config/csky/csky_tables.opt    |  21 +
>   gcc/config/csky/predicates.md      |   3 +-
>   gcc/config/csky/t-csky-elf         |   9 +-
>   gcc/config/csky/t-csky-linux       |  11 +-
>   gcc/doc/md.texi                    |   8 +
>   16 files changed, 2125 insertions(+), 675 deletions(-)
>   create mode 100644 gcc/config/csky/csky-modes.def
>   create mode 100644 gcc/config/csky/csky_insn_fpuv2.md
>   create mode 100644 gcc/config/csky/csky_insn_fpuv3.md
>
> diff --git a/gcc/config/csky/constraints.md b/gcc/config/csky/constraints.md
> index 6067d3d..937cb81 100644
> --- a/gcc/config/csky/constraints.md
> +++ b/gcc/config/csky/constraints.md
> @@ -34,7 +34,11 @@
>   
>   (define_memory_constraint "Q"
>     "Memory operands with base register, index register and short displacement for FPUV2"
> -  (match_test "csky_valid_fpuv2_mem_operand (op)"))
> +  (match_test "csky_valid_mem_constraint_operand (op, \"Q\")"))
> +
> +(define_memory_constraint "W"
> +  "Memory operands with base register, index register"
> +  (match_test "csky_valid_mem_constraint_operand (op, \"W\")"))
>   
>   (define_constraint "R"
>     "Memory operands whose address is a label_ref"
> @@ -172,3 +176,10 @@
>     "Constant in range [-8, -1]"
>     (and (match_code "const_int")
>          (match_test "CSKY_CONST_OK_FOR_US (ival)")))
> +
> +(define_constraint "Dv"
> + "@VFPv3
> +  A const_double which can be used with a VFP fmovi
> +  instruction."
> +  (and (match_code "const_double")
> +       (match_test "fpuv3_const_double_rtx (op)")))
> diff --git a/gcc/config/csky/csky-modes.def b/gcc/config/csky/csky-modes.def
> new file mode 100644
> index 0000000..a2427ff
> --- /dev/null
> +++ b/gcc/config/csky/csky-modes.def
> @@ -0,0 +1,2 @@
> +/* Float modes.  */
> +FLOAT_MODE (HF, 2, ieee_half_format);        /* Half-precision floating point */
> diff --git a/gcc/config/csky/csky-protos.h b/gcc/config/csky/csky-protos.h
> index 7a2e23e..7c6528b 100644
> --- a/gcc/config/csky/csky-protos.h
> +++ b/gcc/config/csky/csky-protos.h
> @@ -30,7 +30,7 @@ extern void csky_cpu_cpp_builtins (cpp_reader *);
>   extern bool csky_inlinable_constant (HOST_WIDE_INT value);
>   extern bool csky_shifted_imm8_constant (unsigned HOST_WIDE_INT,
>   					unsigned int *, unsigned int *);
> -extern bool csky_valid_fpuv2_mem_operand (rtx);
> +extern bool csky_valid_mem_constraint_operand (rtx, const char*);
>   
>   extern bool csky_minipool_load_p (rtx_insn *);
>   extern const char *csky_output_move (rtx insn, rtx *, machine_mode);
> @@ -70,4 +70,9 @@ extern int csky_default_branch_cost (bool, bool);
>   extern bool csky_default_logical_op_non_short_circuit (void);
>   
>   extern void csky_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
> +extern int csky_get_movedouble_length(rtx operands[]);
> +
> +/* The functions was used for fpuv3.  */
> +extern const char *fpuv3_output_move (rtx *operands);
> +extern int fpuv3_const_double_rtx (rtx);
>   #endif /* GCC_CSKY_PROTOS_H */
> diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
> index cdb95fe..6e97994 100644
> --- a/gcc/config/csky/csky.c
> +++ b/gcc/config/csky/csky.c
> @@ -126,7 +126,46 @@ enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER] =
>     /* Reserved.  */
>     RESERVE_REGS, RESERVE_REGS,
>     /* Register epc.  */
> -  OTHER_REGS
> +  OTHER_REGS,
> +  /* Vec registers.  */
> +  V_REGS,       V_REGS,       V_REGS,       V_REGS,
> +  V_REGS,       V_REGS,       V_REGS,       V_REGS,
> +  V_REGS,       V_REGS,       V_REGS,       V_REGS,
> +  V_REGS,       V_REGS,       V_REGS,       V_REGS,
> +  /* Reserved.  */
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  /* Reserved.  */
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
> +
> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS
>   };
>   
>   /* Arrays that map GCC register numbers to debugger register numbers,
> @@ -138,11 +177,34 @@ const int csky_dbx_regno[FIRST_PSEUDO_REGISTER] =
>     8,  9,  10, 11, 12, 13, 14, 15,
>     16, 17, 18, 19, 20, 21, 22, 23,
>     24, 25, 26, 27, 28, 29, 30, 31,
> -  -1, -1, 36, 37, -1, -1, -1, -1,
> -  -1, -1, -1, -1, -1, -1, -1, -1,
> -  -1, -1, -1, -1, 56, 57, 58, 59,
> -  60, 61, 62, 63, 64, 65, 66, 67,
> -  68, 69, 70, 71, -1, -1, 72
> +  -1, -1, 36, 37,
> +  75,  79,  83,  87,  91,  95,  99,  103,
> +  107, 111, 115, 119, 123, 127, 131, 135,
> +  74,  78,  82,  86,  90,  94,  98,  102,
> +  106, 110, 114, 118, 122, 126, 130, 134,
> +  -1, -1, 72,
> +  /* vr: 71 - 86 */
> +  139,  143,  147,  151,  155,  159,  163,  167,
> +  171,  175,  179,  183,  187,  191,  195,  199,
> +  138,  142,  146,  150,  154,  158,  162,  166,
> +  170,  174,  178,  182,  186,  190,  194,  198,
> +  /* resereved */
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
> +
> +  -1,   -1,   -1
>   };
>   
>   /* Table of machine attributes.  */
> @@ -351,6 +413,12 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
>         builtin_define ("__CSKY_FPUV2__");
>       }
>   
> +  if (TARGET_SUPPORT_FPV3)
> +    {
> +      builtin_define ("__csky_fpuv3__");
> +      builtin_define ("__CSKY_FPUV3__");
> +    }
> +
>     if (TARGET_ELRW)
>       {
>         builtin_define ("__csky_elrw__");
> @@ -408,7 +476,6 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
>    *			   Storage Layout			  *
>    ******************************************************************/
>   
> -
>   #undef	TARGET_PROMOTE_FUNCTION_MODE
>   #define TARGET_PROMOTE_FUNCTION_MODE \
>     default_promote_function_mode_always_promote
> @@ -416,6 +483,9 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
>   #undef TARGET_CONSTANT_ALIGNMENT
>   #define TARGET_CONSTANT_ALIGNMENT csky_constant_alignment
>   
> +#undef TARGET_MANGLE_TYPE
> +#define TARGET_MANGLE_TYPE csky_mangle_type
> +
>   
>   /******************************************************************
>    *		Stack Layout and Calling Conventions		  *
> @@ -692,6 +762,15 @@ csky_default_logical_op_non_short_circuit (void)
>   #define	 TARGET_SCHED_ADJUST_COST csky_sched_adjust_cost
>   
>   
> +/******************************************************************
> + *			Builtin					  *
> + ******************************************************************/
> +
> +
> +#undef  TARGET_INIT_BUILTINS
> +#define TARGET_INIT_BUILTINS  csky_init_builtins
> +
> +
>   /* The declaration of functions.  */
>   static void push_csky_minipool_fix (rtx_insn *, HOST_WIDE_INT, rtx *,
>   				    machine_mode, rtx);
> @@ -837,6 +916,7 @@ Mfix *minipool_fix_tail;
>   Mfix *minipool_barrier;
>   
>   /* Allow GC scanning of the minipool obstack.  */
> +
>   static void
>   csky_add_gc_roots (void)
>   {
> @@ -846,6 +926,7 @@ csky_add_gc_roots (void)
>   
>   /* Implement TARGET_CONSTANT_ALIGNMENT.
>      Make strings word-aligned so strcpy from constants will be faster.  */
> +
>   static HOST_WIDE_INT
>   csky_constant_alignment (const_tree exp, HOST_WIDE_INT align)
>   {
> @@ -1109,6 +1190,7 @@ get_csky_barrier_cost (rtx_insn *insn)
>      (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
>      Create the barrier by inserting a jump and add a new fix entry for
>      it.  */
> +
>   static Mfix *
>   create_csky_fix_barrier (Mfix *fix, Mfix *fix_next,
>   			 HOST_WIDE_INT max_address)
> @@ -1455,6 +1537,7 @@ csky_compute_pushpop_length (rtx *operands)
>   }
>   
>   /* Emit constant pools for -mconstpool.  */
> +
>   static void
>   csky_emit_constant_pools (void)
>   {
> @@ -1796,6 +1879,7 @@ csky_initial_elimination_offset (int from, int to)
>      CUM is a variable of type CUMULATIVE_ARGS which gives info about
>       the preceding args and about the function being called.
>      ARG is a description of the argument.  */
> +
>   static rtx
>   csky_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>   {
> @@ -1921,6 +2005,7 @@ csky_function_value (const_tree type, const_tree func,
>   
>   
>   /* Implement TARGET_LIBCALL_VALUE.  */
> +
>   static rtx
>   csky_libcall_value (machine_mode mode,
>   		    const_rtx libcall ATTRIBUTE_UNUSED)
> @@ -1949,6 +2034,7 @@ csky_function_value_regno_p (const unsigned int regno)
>   
>   /* Return an RTX indicating where the return address to the
>      calling function can be found.  */
> +
>   rtx
>   csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
>   {
> @@ -1964,6 +2050,7 @@ csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
>      that must be put in registers. The value must be zero for arguments
>      that are passed entirely in registers or
>      that are entirely pushed on the stack.  */
> +
>   static int
>   csky_arg_partial_bytes (cumulative_args_t pcum_v, const function_arg_info &arg)
>   {
> @@ -2180,7 +2267,19 @@ csky_conditional_register_usage (void)
>         int regno;
>   
>         for (regno = CSKY_FIRST_VFP_REGNUM;
> -	   regno <= CSKY_LAST_VFP_REGNUM; regno++)
> +	   regno <= CSKY_LAST_VFP3_REGNUM; regno++)
> +	{
> +	  fixed_regs[regno] = 1;
> +	  call_used_regs[regno] = 1;
> +	}
> +    }
> +
> +  if (!TARGET_SUPPORT_FPV3)
> +    {
> +      int regno;
> +
> +      for (regno = CSKY_FIRST_VFP3_REGNUM;
> +	   regno <= CSKY_LAST_VFP3_REGNUM; regno++)
>   	{
>   	  fixed_regs[regno] = 1;
>   	  call_used_regs[regno] = 1;
> @@ -2198,6 +2297,7 @@ csky_conditional_register_usage (void)
>   }
>   
>   /* Implement TARGET_HARD_REGNO_NREGS.  */
> +
>   static unsigned int
>   csky_hard_regno_nregs (unsigned int regno, machine_mode mode)
>   {
> @@ -2261,6 +2361,7 @@ csky_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
>   /* Implement TARGET_MODES_TIEABLE_P.  We can't tie DFmode with other modes
>      when V_REGs might be in use because those registers mess with the stored
>      bits.  */
> +
>   static bool
>   csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
>   {
> @@ -2272,6 +2373,7 @@ csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
>   /* Implement TARGET_CAN_CHANGE_MODE_CLASS.
>      V_REG registers can't do subreg as all values are reformatted to
>      internal precision.  */
> +
>   static bool
>   csky_can_change_mode_class (machine_mode from,
>   			    machine_mode to,
> @@ -2406,6 +2508,7 @@ csky_spill_class (reg_class_t rclass, machine_mode mode ATTRIBUTE_UNUSED)
>   
>   /* Convert a static initializer array of feature bits to sbitmap
>      representation.  */
> +
>   static void
>   csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
>   {
> @@ -2417,6 +2520,7 @@ csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
>   
>   /* Configure a build target TARGET from the user-specified options OPTS and
>      OPTS_SET.  */
> +
>   static void
>   csky_configure_build_target (struct csky_build_target *target,
>   			     struct cl_target_option *opts,
> @@ -2508,7 +2612,9 @@ csky_option_override (void)
>   
>     csky_base_arch = csky_active_target.base_arch;
>   
> -  if (flag_pic && !(CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK807)))
> +  if (flag_pic && !(CSKY_TARGET_ARCH (CK807)
> +		   || CSKY_TARGET_ARCH (CK810)
> +		   || CSKY_TARGET_ARCH (CK860)))
>       {
>         flag_pic = 0;
>         warning (0, "%qs is not supported by arch %s",
> @@ -2526,19 +2632,21 @@ csky_option_override (void)
>   	  bool ok;
>   	  int fpu_index;
>   
> -#ifdef CSKY_FPUTYPE_DEFAULT
> -	  target_fpu_name = CSKY_FPUTYPE_DEFAULT;
> -#else
> -	  target_fpu_name = "fpv2";
> -#endif
> -
>   	  if (csky_active_target.core_name != NULL
>   	      && !strchr (csky_active_target.core_name, 'f'))
>   	    target_fpu_name = "auto";
>   	  else if (CSKY_TARGET_ARCH (CK803) || !TARGET_DOUBLE_FLOAT)
>   	    target_fpu_name = "fpv2_sf";
> +	  else if (CSKY_TARGET_ARCH (CK860))
> +	    target_fpu_name = "fpv3";
>   	  else if (TARGET_DOUBLE_FLOAT && TARGET_FDIVDU)
>   	    target_fpu_name = "fpv2_divd";
> +	  else
> +#ifdef CSKY_FPUTYPE_DEFAULT
> +	    target_fpu_name = CSKY_FPUTYPE_DEFAULT;
> +#else
> +	    target_fpu_name = "fpv2";
> +#endif
>   
>   	  ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &fpu_index,
>   				      CL_TARGET);
> @@ -3020,10 +3128,8 @@ ck810_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
>   {
>     enum rtx_code code = GET_CODE (index);
>   
> -  if (TARGET_HARD_FLOAT
> -      && (mode == SFmode || mode == DFmode))
> -    return (code == CONST_INT && INTVAL (index) < 1024
> -	    && INTVAL (index) >= 0
> +  if (code == CONST_INT && TARGET_HARD_FLOAT && CSKY_VREG_MODE_P (mode))
> +    return (INTVAL (index) < 1024 && INTVAL (index) >= 0
>   	    && (INTVAL (index) & 3) == 0);
>   
>     if (code == CONST_INT)
> @@ -3183,7 +3289,7 @@ static bool
>   decompose_csky_address (rtx addr, struct csky_address *out)
>   {
>     rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
> -  HOST_WIDE_INT scale = 1;
> +  HOST_WIDE_INT scale = 0;
>     rtx scale_rtx = NULL_RTX;
>     int i;
>   
> @@ -3231,7 +3337,10 @@ decompose_csky_address (rtx addr, struct csky_address *out)
>   	      if (!base)
>   		base = op;
>   	      else if (!index)
> -		index = op;
> +		{
> +		  index = op;
> +		  scale = 1;
> +		}
>   	      else
>   		return false;
>   	      break;
> @@ -3259,7 +3368,7 @@ decompose_csky_address (rtx addr, struct csky_address *out)
>   	      scale_rtx = XEXP (op, 1);
>   	      if (!CONST_INT_P (scale_rtx))
>   		return false;
> -	      scale = scale << INTVAL (scale_rtx);
> +	      scale = 1 << INTVAL (scale_rtx);
>   	      break;
>   	    default:
>   	      return false;
> @@ -3484,6 +3593,14 @@ csky_print_operand (FILE *stream, rtx x, int code)
>   	case UNSPEC:
>   	  csky_output_pic_addr_const (stream, x, code);
>   	  break;
> +	case CONST_DOUBLE:
> +	  {
> +	    char fpstr[20];
> +	    real_to_decimal ( fpstr, CONST_DOUBLE_REAL_VALUE (x),
> +			     sizeof (fpstr), 0, 1);
> +	    fprintf (stream, "%s", fpstr);
> +	  }
> +	  break;
>   	default:
>   	  output_addr_const (stream, x);
>   	  break;
> @@ -3997,17 +4114,37 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   		return "mfhi\t%0";
>   	    }
>   
> -	    if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
> -	      return "fmovs\t%0, %1";
> -	    if (CSKY_VREG_P (dstreg))
> -	      return "fmtvrl\t%0, %1";
> -	    if (CSKY_VREG_P (srcreg))
> -	      return "fmfvrl\t%0, %1";
> -
> -	    if (REGNO (src) == CSKY_CC_REGNUM)
> -	      return "mvc\t%0";
> -	    else
> -	      return "mov\t%0, %1";
> +	  if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
> +	    {
> +	      if (CSKY_ISA_FEATURE (fpv2_sf))
> +		return "fmovs\t%0, %1";
> +	      else if (CSKY_ISA_FEATURE (fpv3_sf))
> +		return "fmov.32\t%0, %1";
> +	      else
> +		gcc_unreachable ();
> +	    }
> +	  if (CSKY_VREG_P (dstreg))
> +	    {
> +	      if (CSKY_ISA_FEATURE (fpv2_sf))
> +		return "fmtvrl\t%0, %1";
> +	      else if (CSKY_ISA_FEATURE (fpv3_sf))
> +		return "fmtvr.32.1\t%0, %1";
> +	      else
> +		gcc_unreachable ();
> +	    }
> +	  if (CSKY_VREG_P (srcreg))
> +	    {
> +	      if (CSKY_ISA_FEATURE (fpv2_sf))
> +		return "fmfvrl\t%0, %1";
> +	      else if (CSKY_ISA_FEATURE (fpv3_sf))
> +		return "fmfvr.32.1\t%0, %1";
> +	      else
> +		gcc_unreachable ();
> +	    }
> +	  if (REGNO (src) == CSKY_CC_REGNUM)
> +	    return "mvc\t%0";
> +	  else
> +	    return "mov\t%0, %1";
>   	}
>         /* The situation mov memory to reg.  */
>         else if (GET_CODE (src) == MEM)
> @@ -4018,13 +4155,21 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	    switch (GET_MODE (src))
>   	      {
>   	      case E_HImode:
> +	      case E_HFmode:
>   		return "ldr.h\t%0, %1";
>   	      case E_QImode:
>   		return "ldr.b\t%0, %1";
>   	      case E_SImode:
>   	      case E_SFmode:
>   		if (CSKY_VREG_P (REGNO (dst)))
> -		  return "fldrs\t%0, %1";
> +		  {
> +		    if (CSKY_ISA_FEATURE(fpv2_sf))
> +		      return "fldrs\t%0, %1";
> +		    else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		      return "fldr.32\t%0, %1";
> +		    else
> +		      gcc_unreachable ();
> +		    }
>   		else
>   		  return "ldr.w\t%0, %1";
>   	      default:
> @@ -4042,13 +4187,21 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	    switch (GET_MODE (src))
>   	      {
>   	      case E_HImode:
> +	      case E_HFmode:
>   		return "ld.h\t%0, %1";
>   	      case E_QImode:
>   		return "ld.b\t%0, %1";
>   	      case E_SFmode:
>   	      case E_SImode:
>   		if (CSKY_VREG_P (REGNO (dst)))
> -		  return "flds\t%0, %1";
> +		  {
> +		     if (CSKY_ISA_FEATURE(fpv2_sf))
> +		       return "flds\t%0, %1";
> +		     else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		       return "fld.32\t%0, %1";
> +		     else
> +		       gcc_unreachable ();
> +		   }
>   		else
>   		  return "ld.w\t%0, %1";
>   	      default:
> @@ -4106,7 +4259,14 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	  case E_SFmode:
>   	  case E_SImode:
>   	    if (CSKY_VREG_P (REGNO (src)))
> -	      return "fstrs\t%1, %0";
> +	      {
> +		if (CSKY_ISA_FEATURE(fpv2_sf))
> +		  return "fstrs\t%1, %0";
> +		else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		  return "fstr.32\t%1, %0";
> +		else
> +		  gcc_unreachable ();
> +	      }
>   	    else
>   	      return "str.w\t%1, %0";
>   	  default:
> @@ -4122,7 +4282,14 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	  case E_SImode:
>   	  case E_SFmode:
>   	    if (CSKY_VREG_P (REGNO (src)))
> -	      return "fsts\t%1, %0";
> +	      {
> +		if (CSKY_ISA_FEATURE(fpv2_sf))
> +		  return "fsts\t%1, %0";
> +		else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		  return "fst.32\t%1, %0";
> +		else
> +		  gcc_unreachable ();
> +	      }
>   	    else
>   	      return "st.w\t%1, %0";
>   	  default:
> @@ -4261,7 +4428,14 @@ csky_output_movedouble (rtx operands[],
>   		return "mthi\t%R1\n\tmtlo\t%1";
>   	    }
>   	  else if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
> -	    return "fmovd\t%0, %1";
> +	    {
> +	      if (CSKY_ISA_FEATURE(fpv2_df))
> +		return "fmovd\t%0, %1";
> +	      else if (CSKY_ISA_FEATURE(fpv3_df))
> +		return "fmov.64\t%0, %1";
> +	      else
> +		gcc_unreachable ();
> +	    }
>   	  else if (CSKY_VREG_P (srcreg))
>   	    {
>   	      /* Since the vector registers in fpuv2_soft processors
> @@ -4270,18 +4444,46 @@ csky_output_movedouble (rtx operands[],
>   	      if (TARGET_SOFT_FPU)
>   		  return "fmfvrl\t%0, %1";
>   	      else if (TARGET_BIG_ENDIAN)
> -		return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fmfvr.64\t%R0, %0, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	      else
> -		return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fmfvr.64\t%0, %R0, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	    }
>   	  else if (CSKY_VREG_P (dstreg))
>   	    {
>   	      if (TARGET_SOFT_FPU)
>   		return "fmtvrl\t%0, %1";
>   	      else if (TARGET_BIG_ENDIAN)
> -		return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fmtvr.64\t%0, %R1, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	      else
> -		return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fmtvr.64\t%0, %1, %R1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	    }
>   
>   	  /* Ensure the second source not overwritten.  */
> @@ -4323,9 +4525,23 @@ csky_output_movedouble (rtx operands[],
>   	  if (CSKY_VREG_P (dstreg))
>   	    {
>   	      if (op0.index)
> -		return "fldrd\t%0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fldrd\t%0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fldr.64\t%0, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	      else
> -		return "fldd\t%0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fldd\t%0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fld.64\t%0, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	    }
>   	  /* FIXME length attribute is wrong here.  */
>   	  if (dstreg == basereg)
> @@ -4389,9 +4605,23 @@ csky_output_movedouble (rtx operands[],
>         if (CSKY_VREG_P (srcreg))
>   	{
>   	  if (op0.index)
> -	    return "fstrd\t%1, %0";
> +	    {
> +	      if (CSKY_ISA_FEATURE(fpv2_df))
> +		return "fstrd\t%1, %0";
> +	      else if (CSKY_ISA_FEATURE(fpv3_df))
> +		return "fstr.64\t%1, %0";
> +	      else
> +		gcc_unreachable ();
> +	    }
>   	  else
> -	    return "fstd\t%1, %0";
> +	    {
> +	      if (CSKY_ISA_FEATURE(fpv2_df))
> +		return "fstd\t%1, %0";
> +	      else if (CSKY_ISA_FEATURE(fpv3_df))
> +		return "fst.64\t%1, %0";
> +	      else
> +		gcc_unreachable ();
> +	    }
>   	}
>         /* FIXME length attribute is wrong here.  */
>         if (srcreg == basereg)
> @@ -4518,9 +4748,181 @@ csky_output_ck801_movedouble (rtx operands[],
>       gcc_unreachable ();
>   }
>   
> +/* Calculate the instruction's length for moving double-word data.  */
> +
> +int
> +csky_get_movedouble_length(rtx operands[])
> +{
> +  rtx dst = operands[0];
> +  rtx src = operands[1];
> +
> +  if (REG_P (dst))
> +    {
> +      if (REG_P (src))
> +	{
> +	  int dstreg = REGNO (dst);
> +	  int srcreg = REGNO (src);
> +
> +	  if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
> +	    return 4;
> +	  else
> +	    return 8;
> +	}
> +      else if (GET_CODE (src) == MEM)
> +	{
> +	  rtx memexp = XEXP (src, 0);
> +	  int dstreg = REGNO (dst);
> +	  struct csky_address op0;
> +	  decompose_csky_address (XEXP (src, 0), &op0);
> +
> +	  if (GET_CODE (memexp) == LABEL_REF)
> +	    return 8;
> +	  if (CSKY_VREG_P (dstreg))
> +	    return 4;
> +	  return 8;
> +	}
> +      else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
> +	{
> +	  split_double (src, operands + 2, operands + 3);
> +	  if (CSKY_CONST_OK_FOR_N (INTVAL (operands[2]) + 1)
> +	      && CSKY_CONST_OK_FOR_N (INTVAL (operands[3]) + 1)
> +	      && REGNO (operands[0]) < 6)
> +	    return 4;
> +	  else
> +	    return 8;
> +	}
> +    }
> +  else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
> +    {
> +      rtx memexp = XEXP (dst, 0);
> +      int srcreg = REGNO (src);
> +      int offset = -1;
> +      if (CSKY_VREG_P (srcreg))
> +	return 4;
> +
> +      if (GET_CODE (memexp) == REG)
> +	offset = 0;
> +      else if (GET_CODE (memexp) == PLUS)
> +	{
> +	  if (GET_CODE (XEXP (memexp, 0)) == REG)
> +	    offset = INTVAL (XEXP (memexp, 1));
> +	  else if (GET_CODE (XEXP (memexp, 1)) == REG)
> +	    offset = INTVAL (XEXP (memexp, 0));
> +	  else
> +	    gcc_unreachable ();
> +	}
> +      else
> +	gcc_unreachable ();
> +
> +      if (srcreg <= 6 && offset <= 1020)
> +	return 4;
> +      else if ((srcreg == 7 && offset <= 1024) || (srcreg <= 7 && offset == 1024))
> +	return 6;
> +      else
> +	return 8;
> +    }
> +  else
> +    gcc_unreachable ();
> +
> +  return 0;
> +}
> +
> +/* Output float point load/store instructions for fpuv3.  */
> +
> +const char *
> +fpuv3_output_move (rtx *operands)
> +{
> +  rtx reg, mem, addr, ops[2];
> +  bool isload = REG_P (operands[0]);
> +
> +  const char *templ = "f%s%s.%s\t%%0, %%1";
> +  char buff[50];
> +  machine_mode mode;
> +
> +  reg = operands[isload ? 0 : 1];
> +  mem = operands[isload ? 1 : 0];
> +
> +  gcc_assert (REG_P (reg));
> +  gcc_assert (CSKY_VREG_P (REGNO (reg)));
> +  gcc_assert (MEM_P (mem));
> +
> +  mode = GET_MODE (reg);
> +  const char *type = mode == DFmode ? "64" :
> +		     mode == SFmode ? "32" :
> +		     mode == HFmode ? "16" :
> +		     NULL;
> +  gcc_assert(type != NULL);
> +
> +  addr = XEXP (mem, 0);
> +  struct csky_address caddr;
> +  decompose_csky_address (addr, &caddr);
> +
> +  ops[0] = reg;
> +  ops[1] = mem;
> +  sprintf (buff, templ,
> +	   isload ? "ld" : "st",
> +	   caddr.index ? "r" : "",
> +	   type);
> +  output_asm_insn (buff, ops);
> +
> +  return "";
> +}
> +
> +/* Check if a const_double can be used by a VFP fmovi instruction.  */
> +
> +int
> +fpuv3_const_double_rtx (rtx x)
> +{
> +  REAL_VALUE_TYPE r, m;
> +  r = *CONST_DOUBLE_REAL_VALUE (x);
> +
> +  /* Fpuv3 doesn't support the following values.  */
> +  if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r) || REAL_VALUE_MINUS_ZERO (r)
> +      || r.cl == rvc_zero)
> +    return 0;
> +
> +  /* Extract sign, exponent and mantissa.  */
> +  int exponent;
> +  r = real_value_abs (&r);
> +  exponent = REAL_EXP (&r);
> +
> +  bool fail;
> +  unsigned HOST_WIDE_INT mantissa, mant_hi;
> +  unsigned HOST_WIDE_INT mask;
> +  int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1;
> +  real_ldexp (&m, &r, point_pos - exponent);
> +  wide_int w = real_to_integer (&m, &fail, HOST_BITS_PER_WIDE_INT * 2);
> +  mantissa = w.elt (0);
> +  mant_hi = w.elt (1);
> +
> +  exponent -= 1;
> +
> +  if (!IN_RANGE (exponent, -4, 11))
> +    return 0;
> +
> +  /* If there are bits set in the low part of the mantissa, these values are
> +     not supported.  */
> +  if (mantissa != 0)
> +    return 0;
> +
> +  /* Now, make the mantissa contain the most-significant bits, and the
> +     point_pos indicates the number of these bits.  */
> +  point_pos -= HOST_BITS_PER_WIDE_INT;
> +  mantissa = mant_hi;
> +
> +  /* We can only allow a mantissa of 9 significant digits, top of which is always 1.  */
> +  mask = ((unsigned HOST_WIDE_INT)1 << (point_pos - 9)) - 1;
> +  if ((mantissa & mask) != 0)
> +    return 0;
> +
> +  return 1;
> +}
> +
> +
>   /* Split operands for an AND expression when OPERANDS[2] is a constant.
>      Note operands[0] is marked earlyclobber in this case and can be
>      overwritten.  Return true if "DONE", false otherwise.  */
> +
>   bool
>   csky_split_and (rtx *operands)
>   {
> @@ -4650,6 +5052,7 @@ csky_split_and (rtx *operands)
>   /* Split operands for an IOR expression when OPERANDS[2] is a constant.
>      Note operands[0] is marked earlyclobber in this case and can be
>      overwritten.  Return true if "DONE", false otherwise.  */
> +
>   bool
>   csky_split_ior (rtx *operands)
>   {
> @@ -4717,6 +5120,7 @@ csky_split_ior (rtx *operands)
>   /* Split operands for an XOR expression when OPERANDS[2] is a constant.
>      Note operands[0] is marked earlyclobber in this case and can be
>      overwritten.  Return true if "DONE", false otherwise.  */
> +
>   bool
>   csky_split_xor (rtx *operands)
>   {
> @@ -4765,6 +5169,7 @@ csky_split_xor (rtx *operands)
>   
>   
>   /* Return true if X is an address form involving a symbol or label ref.  */
> +
>   bool
>   csky_symbolic_address_p (rtx x)
>   {
> @@ -4793,6 +5198,9 @@ csky_emit_compare (enum rtx_code code, rtx op0, rtx op1)
>     bool invert;
>     rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
>   
> +  if (GET_MODE_CLASS(GET_MODE (op0)) == MODE_FLOAT)
> +    return csky_emit_compare_float(code, op0, op1);
> +
>     if (GET_CODE (op1) == CONST_INT)
>       {
>         HOST_WIDE_INT val = INTVAL (op1);
> @@ -5707,6 +6115,7 @@ tls_unspec_mentioned_p (rtx x)
>   
>   
>   /* Implement LEGITIMATE_PIC_OPERAND_P.  */
> +
>   bool
>   csky_legitimate_pic_operand_p (rtx x)
>   {
> @@ -5938,33 +6347,20 @@ csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
>       op1 = force_reg (mode, op1);
>   
>     invert = false;
> +
>     switch (code)
>       {
>       case EQ:
>         code = NE;
>         invert = true;
>         break;
> -
> -    case NE:
> -      break;
> -    case LE:
> -      if (op1 == CONST0_RTX (mode))
> -	op1 = force_reg (mode, op1);
> -      break;
>       case GT:
> -      if (op1 == CONST0_RTX (mode))
> -	op1 = force_reg (mode, op1);
> -      break;
> -    case GE:
> -      break;
>       case LT:
> -      if (op1 == CONST0_RTX (mode))
> -	{
> -	  code = GE;
> -	  invert = true;
> -	}
> -      break;
> -    case UNORDERED:
> +    case LE:
> +      if (op1 == CONST0_RTX (mode) && (CSKY_ISA_FEATURE_GET(fpv2_sf)
> +				       || CSKY_ISA_FEATURE_GET(fpv2_df)
> +				       || CSKY_ISA_FEATURE_GET(fpv2_divd)))
> +	op1 = force_reg (mode, op1);
>         break;
>       case ORDERED:
>         code = UNORDERED;
> @@ -5980,10 +6376,11 @@ csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
>     return invert;
>   }
>   
> -/* Support for the Q memory constraint.  Returns true if OP is a MEM RTX
> -   with an address consisting of base + index or base + displacement.  */
> +/* Support for the Q or W memory constraint.  Returns true if OP is a MEM
> +   RTX with an address consisting of base + index or base + displacement.  */
> +
>   bool
> -csky_valid_fpuv2_mem_operand (rtx op)
> +csky_valid_mem_constraint_operand (rtx op, const char *constraint)
>   {
>     struct csky_address addr;
>   
> @@ -5998,7 +6395,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
>       return false;
>   
>     /* Verify index operand. */
> -  if (addr.index)
> +  if (addr.index && (constraint[0] == 'Q' || constraint[0] == 'W'))
>       {
>         if (!is_csky_address_register_rtx_p (addr.index, 0))
>   	return false;
> @@ -6010,7 +6407,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
>         return false;
>       }
>     /* Verify disp operand.  */
> -  else if (addr.disp)
> +  else if (addr.disp && constraint[0] == 'Q')
>       {
>         rtx disp = addr.disp;
>   
> @@ -6023,7 +6420,11 @@ csky_valid_fpuv2_mem_operand (rtx op)
>   
>          return false;
>       }
> -  return true;
> +  else if (constraint[0] == 'Q')
> +  /* Single reg is valid for 'Q'.  */
> +    return true;
> +
> +  return false;
>   }
>   
>   
> @@ -6442,7 +6843,7 @@ ck803_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
>       }
>   }
>   
> -/* TARGET_RTX_COSTS helper for ck807+ arches.  */
> +/* TARGET_RTX_COSTS helper for ck807/ck810 arches.  */
>   
>   static bool
>   ck807_ck810_rtx_costs (rtx x, int code,
> @@ -6473,6 +6874,52 @@ ck807_ck810_rtx_costs (rtx x, int code,
>       }
>   }
>   
> +/* TARGET_RTX_COSTS helper for ck860 arches.  */
> +
> +static bool
> +ck860_rtx_costs (rtx x, int code, machine_mode mode,
> +		 int outer_code ATTRIBUTE_UNUSED,
> +		 int *total, bool speed ATTRIBUTE_UNUSED)
> +{
> +  switch (code)
> +    {
> +    case PLUS:
> +      /* The costs of mula is 1 more than mult.  */
> +      if (GET_CODE (XEXP (x, 0)) == MULT && REG_P (XEXP (x, 1)) && speed)
> +	{
> +	  rtx mul_op0 = XEXP (XEXP (x, 0), 0);
> +	  rtx mul_op1 = XEXP (XEXP (x, 0), 1);
> +	  if (REG_P (mul_op0) && REG_P (mul_op1))
> +	    {
> +	      *total = COSTS_N_INSNS (1);
> +	      *total += rtx_cost (XEXP (x, 0), mode,
> +				  (enum rtx_code) code, 0, speed);
> +	      return true;
> +	    }
> +	}
> +      return false;
> +    case MULT:
> +      if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
> +	{
> +	  HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
> +	  if (val % 2 == 0 && val < 0xffffffff && val > 0)
> +	    {
> +	      *total = COSTS_N_INSNS (1);
> +	      return true;
> +	    }
> +	}
> +      return false;
> +
> +    case CONST:
> +    case LABEL_REF:
> +    case SYMBOL_REF:
> +      *total = COSTS_N_INSNS (3);
> +      return true;
> +    default:
> +      return false;
> +    }
> +}
> +
>   
>   /* Implement TARGET_RTX_COSTS, to compute a (partial) cost for rtx X.
>      Return true if the complete cost has been computed, and false if
> @@ -6491,6 +6938,8 @@ csky_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
>       return ck803_rtx_costs (x, code, outer_code, total, speed);
>     else if (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
>       return ck807_ck810_rtx_costs (x, code, outer_code, total, speed);
> +  else if (CSKY_TARGET_ARCH (CK860))
> +    return ck860_rtx_costs (x, code, mode, outer_code, total, speed);
>     else
>       gcc_unreachable ();
>   }
> @@ -6633,6 +7082,7 @@ csky_warn_func_return (tree decl)
>   /* Implement TARGET_RETURN_IN_MEMORY to decide whether TYPE should be
>      returned in memory (true) or in a register (false).
>      FNTYPE is the type of the function making the call.  */
> +
>   static bool
>   csky_return_in_memory (const_tree type,
>   		       const_tree fntype ATTRIBUTE_UNUSED)
> @@ -6646,6 +7096,7 @@ csky_return_in_memory (const_tree type,
>      Dwarf models VFP registers as  64-bit or 128-bit registers default.
>      GCC models tham as 32-bit registers, so we need to describe this to
>      the DWARF generation code.  Other registers can use the default.  */
> +
>   static rtx
>   csky_dwarf_register_span (rtx rtl)
>   {
> @@ -6659,11 +7110,15 @@ csky_dwarf_register_span (rtx rtl)
>     if (!CSKY_VREG_P (regno))
>       return NULL_RTX;
>   
> +  if (CSKY_VREG_HI_P (regno))
> +    regno += 16;
> +
>     mode = GET_MODE (rtl);
>     if (GET_MODE_SIZE (mode) < 8)
>       return NULL_RTX;
>   
> -  if (TARGET_SOFT_FPU)
> +
> +  if (TARGET_SINGLE_FPU)
>       {
>         nregs = GET_MODE_SIZE (mode) / 4;
>         for (i = 0; i < nregs; i += 2)
> @@ -6684,9 +7139,18 @@ csky_dwarf_register_span (rtx rtl)
>   	 as the CPU bit width. Transform the 64-bit FPU registers to
>   	 32 bits here, and we will modify the unwind processing to
>   	 fit CSKY architecture later.  */
> -      nregs = GET_MODE_SIZE (mode) / 8;
> -      for (i = 0; i < nregs; i++)
> -	parts[i] = gen_rtx_REG (SImode, regno + i);
> +      nregs = GET_MODE_SIZE (mode) / 4;
> +      for (i = 0; i < nregs; i += 2)
> +	if (TARGET_BIG_ENDIAN)
> +	  {
> +	    parts[i] = gen_rtx_REG (SImode, regno + i - 16);
> +	    parts[i + 1] = gen_rtx_REG (SImode, regno + i);
> +	  }
> +	else
> +	  {
> +	    parts[i] = gen_rtx_REG (SImode, regno + i);
> +	    parts[i + 1] = gen_rtx_REG (SImode, regno + i - 16);
> +	  }
>       }
>   
>     return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nregs , parts));
> @@ -6847,6 +7311,34 @@ csky_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
>       pcum->is_stdarg = true;
>   }
>   
> +
> +/* Implement the TARGET_INIT_BUILTINS target macro.  */
> +
> +void
> +csky_init_builtins (void)
> +{
> +  /* Inint fp16.  */
> +  static tree csky_floatHF_type_node = make_node (REAL_TYPE);
> +  TYPE_PRECISION (csky_floatHF_type_node) = GET_MODE_PRECISION (HFmode);
> +  layout_type (csky_floatHF_type_node);
> +  (*lang_hooks.types.register_builtin_type) (csky_floatHF_type_node, "__fp16");
> +}
> +
> +
> +/* Implement TARGET_MANGLE_TYPE.  */
> +
> +static const char *
> +csky_mangle_type (const_tree type)
> +{
> +  if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
> +      && DECL_NAME (TYPE_NAME (type))
> +      && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), "__fp16"))
> +    return "__fp16";
> +
> +  /* Use the default mangling.  */
> +  return NULL;
> +}
> +
>   struct gcc_target targetm = TARGET_INITIALIZER;
>   
>   #include "gt-csky.h"
> diff --git a/gcc/config/csky/csky.h b/gcc/config/csky/csky.h
> index c7590ab..f535c42 100644
> --- a/gcc/config/csky/csky.h
> +++ b/gcc/config/csky/csky.h
> @@ -28,8 +28,17 @@
>   #define CSKY_GENERAL_REGNO_P(N)			\
>     ((N) < CSKY_NGPR_REGS && (int)(N) >= 0)
>   
> -#define CSKY_VREG_P(N)		     \
> -  ((N) >= CSKY_FIRST_VFP_REGNUM && (N) <= CSKY_LAST_VFP_REGNUM)
> +#define CSKY_VREG_LO_P(N) \
> +  ((N) >= CSKY_FIRST_VFP_REGNUM \
> +   && (N) <= CSKY_LAST_VFP_REGNUM)
> +
> + #define CSKY_VREG_HI_P(N) \
> +   ((N) >= CSKY_FIRST_VFP3_REGNUM \
> +    && (N) <= CSKY_LAST_VFP3_REGNUM)
> +
> + #define CSKY_VREG_P(N)    \
> +   (CSKY_VREG_LO_P(N)     \
> +    || CSKY_VREG_HI_P(N))
>   
>   #define CSKY_HILO_REG_P(N)   \
>     ((N) == CSKY_HI_REGNUM || (N) == CSKY_LO_REGNUM)
> @@ -124,7 +133,7 @@
>     (optimize_size && TARGET_CONSTANT_POOL \
>      && (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802)))
>   #define TARGET_TLS \
> -  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
> +  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK860))
>   
>   /* Run-time Target Specification.  */
>   #define TARGET_SOFT_FLOAT       (csky_float_abi == CSKY_FLOAT_ABI_SOFT)
> @@ -133,7 +142,9 @@
>   /* Use hardware floating point calling convention.  */
>   #define TARGET_HARD_FLOAT_ABI   (csky_float_abi == CSKY_FLOAT_ABI_HARD)
>   
> -#define TARGET_SINGLE_FPU     (csky_fpu_index == TARGET_FPU_fpv2_sf)
> +#define TARGET_SINGLE_FPU     (csky_fpu_index == TARGET_FPU_fpv2_sf \
> +			       || csky_fpu_index == TARGET_FPU_fpv3_hsf \
> +			       || csky_fpu_index == TARGET_FPU_fpv3_hf)
>   #define TARGET_DOUBLE_FPU     (TARGET_HARD_FLOAT && !TARGET_SINGLE_FPU)
>   
>   #define FUNCTION_VARG_REGNO_P(REGNO)      \
> @@ -142,13 +153,18 @@
>   		CSKY_FIRST_VFP_REGNUM + CSKY_NPARM_FREGS - 1))
>   
>   #define CSKY_VREG_MODE_P(mode) \
> -  ((mode) == SFmode || (mode) == DFmode)
> +  ((mode) == SFmode || (mode) == DFmode \
> +   || (CSKY_ISA_FEATURE(fpv3_hf) && (mode) == HFmode))
>   
>   #define FUNCTION_VARG_MODE_P(mode)  \
>     (TARGET_HARD_FLOAT_ABI            \
>      && CSKY_VREG_MODE_P(mode)        \
>      && !(mode == DFmode && TARGET_SINGLE_FPU))
>   
> +#define TARGET_SUPPORT_FPV3 (CSKY_ISA_FEATURE (fpv3_hf)    \
> +			     || CSKY_ISA_FEATURE (fpv3_sf) \
> +			     || CSKY_ISA_FEATURE (fpv3_df))
> +
>   /* Number of loads/stores handled by ldm/stm.  */
>   #define CSKY_MIN_MULTIPLE_STLD	3
>   #define CSKY_MAX_MULTIPLE_STLD	12
> @@ -427,7 +443,7 @@ typedef struct
>    ******************************************************************/
>   
>   
> -#define FIRST_PSEUDO_REGISTER 71
> +#define FIRST_PSEUDO_REGISTER 202
>   
>   /* 1 for registers that have pervasive standard uses
>      and are not available for the register allocator.
> @@ -456,7 +472,31 @@ typedef struct
>    /*  reserved */							\
>        1,	   1,								\
>    /*  epc */								\
> -     1									\
> +     1,									\
> + /* vr16  vr17  vr18  vr19  vr20  vr21  vr22  vr23 */			\
> +     0,    0,    0,    0,    0,    0,    0,    0,			\
> + /* vr24  vr25  vr26  vr27  vr28  vr29  vr30  vr31 */			\
> +     0,    0,    0,    0,    0,    0,    0,    0 ,			\
> + /* reserved */								\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> + /* reserved */								\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +									\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +									\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +									\
> +     1,    1,    1							\
>   }
>   
>   /* Like `CALL_USED_REGISTERS' but used to overcome a historical
> @@ -487,7 +527,31 @@ typedef struct
>    /*  reserved */							\
>        1,	   1,								\
>    /*  epc */								\
> -     1									\
> +     1,									\
> + /*  vr16  vr17  vr18  vr19  vr20  vr21  vr22  vr23*/			\
> +     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
> + /*  vr24  vr25 vr26  vr27  vr28  vr29	 vr30  vr31 */			\
> +     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
> + /*  reserved */							\
> +     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
> +     1,	   1,	 1,    1,    1,	   1,	 1,    1,			\
> + /* reserved */								\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +									\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +									\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +     1,    1,    1,    1,    1,    1,    1,    1,			\
> +									\
> +     1,    1,    1							\
>   }
>   
>   #define REGISTER_NAMES							\
> @@ -510,7 +574,37 @@ typedef struct
>     "vr0", "vr1", "vr2",	"vr3",	"vr4",	"vr5",	"vr6",	"vr7",		\
>     "vr8", "vr9", "vr10", "vr11", "vr12", "vr13", "vr14", "vr15",		\
>     "reserved", "reserved",						\
> -  "epc"									\
> +  "epc",								\
> +  /* V registers: 71~86 */						\
> +  "vr16", "vr17", "vr18", "vr19", "vr20", "vr21", "vr22", "vr23",	\
> +  "vr24", "vr25", "vr26", "vr27", "vr28", "vr29", "vr30", "vr31",	\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved",								\
> +  /* reserved: 87~201*/							\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved",						\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved",						\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved", "reserved", "reserved", "reserved",		\
> +  "reserved", "reserved",						\
> +  "reserved", "reserved", "reserved"					\
>   }
>   
>   /* Table of additional register names to use in user input.  */
> @@ -569,9 +663,16 @@ typedef struct
>        52,   53,	 54,   55,   56,   57,	 58,   59,		\
>   /*  vr8	  vr9	vr10  vr11  vr12  vr13	vr14  vr15 */		\
>        60,   61,	 62,   63,   64,   65,	 66,   67,		\
> +/*  vr16  vr17  vr18  vr18  vr20  vr21	vr22  vr23 */		\
> +     71,   72,	 73,   74,   75,   76,	 77,   78,		\
> +/*  vr24  vr25	vr26  vr27  vr28  vr28	vr30  vr31 */		\
> +     79,   80,	 81,   82,   83,   84,	 85,   86,		\
>   /*  reserved  */						\
>        36,   37,	 38,   39,   40,   41,	 42,   43,		\
>        44,   45,	 46,   47,   48,   49,	 50,   51,		\
> +/*  reserved  */						\
> +     87,   88,	 89,   90,   91,   92,	 93,   94,		\
> +     95,   96,	 97,   98,   99,   100,  101,  102,		\
>   /*  sp	  tls	reserved     c	   reserved	    epc */	\
>        14,   31,	 32,	     33,   68,	 69,	     70	 }
>   
> @@ -616,21 +717,34 @@ enum reg_class
>   
>   /* Define which registers fit in which classes.  This is an initializer
>      for a vector of HARD_REG_SET of length N_REG_CLASSES.  */
> -#define REG_CLASS_CONTENTS					     \
> -{								     \
> -  {0x00000000, 0x00000000, 0x00000000 },  /* NO_REGS	       */    \
> -  {0x000000FF, 0x00000000, 0x00000000 },  /* MINI_REGS	       */    \
> -  {0x00004000, 0x00000000, 0x00000000 },  /* SP_REGS	       */    \
> -  {0x0000FFFF, 0x00000000, 0x00000000 },  /* LOW_REGS	       */    \
> -  {0xFFFFFFFF, 0x00000000, 0x00000000 },  /* GENERAL_REGS      */    \
> -  {0x00000000, 0x00000002, 0x00000000 },  /* C_REGS	       */    \
> -  {0x00000000, 0x00000004, 0x00000000 },  /* HI_REG	       */    \
> -  {0x00000000, 0x00000008, 0x00000000 },  /* LO_REG	       */    \
> -  {0x00000000, 0x0000000c, 0x00000000 },  /* HILO_REGS	       */    \
> -  {0x00000000, 0xFFF00000, 0x0000000F },  /* V_REGS	       */    \
> -  {0x00000000, 0x00000000, 0x00000040 },  /* OTHER_REGS	       */    \
> -  {0x00000000, 0x0FF00001, 0x00000030 },  /* RESERVE_REGS      */    \
> -  {0xFFFFFFFF, 0xFFFFFFFF, 0x0000007F },  /* ALL_REGS	       */    \
> +#define REG_CLASS_CONTENTS						      \
> +{									      \
> +  {0x00000000, 0x00000000, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* NO_REGS	 */   \
> +  {0x000000FF, 0x00000000, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* MINI_REGS     */   \
> +  {0x00004000, 0x00000000, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* SP_REGS	 */   \
> +  {0x0000FFFF, 0x00000000, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* LOW_REGS      */   \
> +  {0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* GENERAL_REGS  */   \
> +  {0x00000000, 0x00000002, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* C_REGS	 */   \
> +  {0x00000000, 0x00000004, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* HI_REG	 */   \
> +  {0x00000000, 0x00000008, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* LO_REG	 */   \
> +  {0x00000000, 0x0000000c, 0x00000000, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* HILO_REGS     */   \
> +  {0x00000000, 0xFFF00000, 0x007FFF8F, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* V_REGS	 */   \
> +  {0x00000000, 0x00000000, 0x00000040, 0x00000000,			      \
> +   0x00000000, 0x00000000, 0x00000000},			/* OTHER_REGS    */   \
> +  {0x00000000, 0x000FFFF1, 0xFF800030, 0xFFFFFFFF,			      \
> +   0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF},			/* RESERVE_REGS  */   \
> +  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,			      \
> +   0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF},			/* ALL_REGS      */   \
>   }
>   
>   /* Return register class from regno.  */
> diff --git a/gcc/config/csky/csky.md b/gcc/config/csky/csky.md
> index 8bb3b2b..c27d627 100644
> --- a/gcc/config/csky/csky.md
> +++ b/gcc/config/csky/csky.md
> @@ -32,6 +32,8 @@
>      (CSKY_FIRST_RET_REGNUM		0)
>      (CSKY_FIRST_VFP_REGNUM		52)
>      (CSKY_LAST_VFP_REGNUM		67)
> +   (CSKY_FIRST_VFP3_REGNUM		71)
> +   (CSKY_LAST_VFP3_REGNUM		86)
>      (CSKY_FIRST_HIGH_REGNUM		16)
>      (CSKY_LAST_HIGH_REGNUM		31)
>      (CSKY_FIRST_MINI_REGNUM		0)
> @@ -423,85 +425,6 @@
>      (set_attr "type" "alu,alu,alu,load,load,store")]
>   )
>   
> -;; Float mov instructions.
> -
> -(define_expand "movsf"
> -  [(set (match_operand:SF 0 "general_operand" "")
> -	(match_operand:SF 1 "general_operand" ""))]
> -  ""
> -  "
> -  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
> -    operands[1] = force_reg (SFmode, operands[1]);
> -  "
> -)
> -
> -;; FIXME: maybe the vreg load/stores should have their own type attr.
> -(define_insn "*csky_movsf_fpv2"
> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v")
> -	(match_operand:SF 1 "general_operand"	   " b,r,r,v,m,mF,r,v,Q,v,m"))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "* return csky_output_move (insn, operands, SFmode);"
> -  [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4")
> -   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
> -)
> -
> -(define_insn "*ck801_movsf"
> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
> -	(match_operand:SF 1 "general_operand"	   " r,m,mF,r"))]
> -  "CSKY_ISA_FEATURE (E1)"
> -  "* return csky_output_ck801_move (insn, operands, SFmode);"
> -  [(set_attr "length" "2,4,4,4")
> -   (set_attr "type" "alu,load,load,store")]
> -)
> -
> -(define_insn "*csky_movsf"
> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
> -	(match_operand:SF 1 "general_operand"	   " b,r,m,mF,r"))]
> -  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_sf)"
> -  "* return csky_output_move (insn, operands, SFmode);"
> - [(set_attr "length" "2,4,4,4,4")
> -  (set_attr "type" "alu,alu,load,load,store")]
> -)
> -
> -
> -(define_expand "movdf"
> -  [(set (match_operand:DF 0 "general_operand" "")
> -	(match_operand:DF 1 "general_operand" ""))]
> -  ""
> -  "
> -  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
> -      operands[1] = force_reg (DFmode, operands[1]);
> -  "
> -)
> -
> -;; FIXME: maybe the vreg load/stores should have their own type attr.
> -(define_insn "*csky_movdf_fpv2"
> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v")
> -	(match_operand:DF 1 "general_operand"	    "b,r,r,v,m,mF,r,v,Q,v,m"))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "* return csky_output_movedouble (operands, DFmode);"
> -  [(set_attr "length" "4,8,8,8,8,8,8,8,8,8,8")
> -   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
> -)
> -
> -(define_insn "*ck801_movdf"
> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
> -	(match_operand:DF 1 "general_operand"	   " r,m,mF,r"))]
> -  "CSKY_ISA_FEATURE (E1)"
> -  "* return csky_output_ck801_movedouble (operands, DFmode);"
> -  [(set_attr "length" "4,8,8,8")
> -   (set_attr "type" "alu,load,load,store")]
> -)
> -
> -(define_insn "*csky_movdf"
> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
> -	(match_operand:DF 1 "general_operand"	   " b,r,m,mF,r"))]
> -  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_df)"
> -  "* return csky_output_movedouble (operands, DFmode);"
> - [(set_attr "length" "4,8,8,8,8")
> -  (set_attr "type" "alu,alu,load,load,store")]
> -)
> -
>   ;; The only CCmode move supported is a nop.  Without this pattern,
>   ;; CSE is unable to eliminate redundant comparisons in conditional
>   ;; execution expressions.
> @@ -522,7 +445,7 @@
>   
>   (define_expand "movsicc"
>     [(set (match_operand 0 "register_operand" "")
> -	(if_then_else:SI (match_operand	   1 "ordered_comparison_operator" "")
> +	(if_then_else:SI (match_operand	   1 "comparison_operator" "")
>   			 (match_operand:SI 2 "register_operand" "")
>   			 (match_operand:SI 3 "register_operand" "")))]
>     "CSKY_ISA_FEATURE (E2)"
> @@ -1321,7 +1244,7 @@
>   
>   (define_expand "addsicc"
>     [(match_operand:SI 0 "register_operand" "")
> -   (match_operand    1 "ordered_comparison_operator" "")
> +   (match_operand    1 "comparison_operator" "")
>      (match_operand:SI 2 "register_operand" "")
>      (match_operand:SI 3 "csky_literal_K_Uh_operand" "")]
>     "CSKY_ISA_FEATURE (E2)"
> @@ -3316,9 +3239,9 @@
>   
>   (define_expand "untyped_call"
>     [(parallel [(call (match_operand 0 "" "")
> -        (const_int 0))
> -        (match_operand 1 "" "")
> -        (match_operand 2 "" "")])]
> +	(const_int 0))
> +	(match_operand 1 "" "")
> +	(match_operand 2 "" "")])]
>     ""
>   {
>     int i;
> @@ -3349,11 +3272,25 @@
>     ""
>     [(set_attr "length" "0")])
>   
> -(define_insn "*call_value_internal_vs"
> -  [(set (match_operand:SF               0 "register_operand"          "=v,v,v")
> +(define_insn "*call_value_internal_vh"
> +  [(set (match_operand:HF               0 "register_operand"          "=v,v,v")
>           (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
>                 (match_operand 2 "" "")))
>      (clobber (reg:SI CSKY_LR_REGNUM))]
> +  "TARGET_HARD_FLOAT_ABI && CSKY_ISA_FEATURE (fpv3_hf)"
> +  "@
> +    jsr\t%1
> +    jsr\t%1
> +    jbsr\t%1"
> +  [(set_attr "length" "2,4,4")
> +   (set_attr "type"   "call_jsr,call_jsr,call")]
> +)
> +
> +(define_insn "*call_value_internal_vs"
> +  [(set (match_operand:SF	       0 "register_operand"	  "=v,v,v")
> +	(call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
> +	      (match_operand 2 "" "")))
> +   (clobber (reg:SI CSKY_LR_REGNUM))]
>     "TARGET_HARD_FLOAT_ABI"
>     "@
>       jsr\t%1
> @@ -3364,9 +3301,9 @@
>   )
>   
>   (define_insn "*call_value_internal_vd"
> -  [(set (match_operand:DF               0 "register_operand"          "=v,v,v")
> -        (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
> -              (match_operand 2 "" "")))
> +  [(set (match_operand:DF	       0 "register_operand"	  "=v,v,v")
> +	(call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
> +	      (match_operand 2 "" "")))
>      (clobber (reg:SI CSKY_LR_REGNUM))]
>     "TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
>     "@
> @@ -3378,18 +3315,18 @@
>   )
>   
>   (define_insn "*call_value_internal_pic_vs"
> -  [(set (match_operand:SF               0 "register_operand"    "=v")
> -        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
> -                      (match_operand    2 "" "")))
> +  [(set (match_operand:SF	       0 "register_operand"    "=v")
> +	(call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
> +		      (match_operand    2 "" "")))
>      (clobber (reg:SI CSKY_LR_REGNUM))]
>     "flag_pic && TARGET_HARD_FLOAT_ABI"
>     "* return csky_output_call (operands, 1);"
>   )
>   
>   (define_insn "*call_value_internal_pic_vd"
> -  [(set (match_operand:DF               0 "register_operand"    "=v")
> -        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
> -                      (match_operand    2 "" "")))
> +  [(set (match_operand:DF	       0 "register_operand"    "=v")
> +	(call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
> +		      (match_operand    2 "" "")))
>      (clobber (reg:SI CSKY_LR_REGNUM))]
>     "flag_pic && TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
>     "* return csky_output_call (operands, 1);"
> diff --git a/gcc/config/csky/csky_cores.def b/gcc/config/csky/csky_cores.def
> index 8309e99..fcf42a4 100644
> --- a/gcc/config/csky/csky_cores.def
> +++ b/gcc/config/csky/csky_cores.def
> @@ -38,6 +38,8 @@ CSKY_ARCH ("ck807",  ck807,  CK807,
>   	   CSKY_ISA_FEAT (CSKY_ISA_CK807) CSKY_ISA_FEAT (CSKY_ISA_DSP))
>   CSKY_ARCH ("ck810",  ck810,  CK810,
>   	   CSKY_ISA_FEAT (CSKY_ISA_CK810) CSKY_ISA_FEAT (CSKY_ISA_DSP))
> +CSKY_ARCH ("ck860",  ck860,  CK860,
> +	   CSKY_ISA_FEAT (CSKY_ISA_CK860))
>   #endif
>   
>   
> @@ -181,6 +183,12 @@ CSKY_CORE ("ck810ft",  ck810ff,	 ck810ft,  CK810,
>   	   CSKY_ISA_FEAT_NONE)
>   CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
>   	   CSKY_ISA_FEAT_NONE)
> +
> +/* ck860 Architecture Processors */
> +CSKY_CORE("ck860",    ck860,    ck860,    CK860,
> +	  CSKY_ISA_FEAT_NONE)
> +CSKY_CORE("ck860f",   ck860f,   ck860f,   CK860,
> +	  CSKY_ISA_FEAT_NONE)
>   #endif
>   
>   
> @@ -196,4 +204,9 @@ CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
>   CSKY_FPU ("fpv2_sf",   fpv2_sf,	  CSKY_ISA_FEAT (CSKY_ISA_FPv2_SF))
>   CSKY_FPU ("fpv2",      fpv2,	  CSKY_ISA_FEAT (CSKY_ISA_FPv2))
>   CSKY_FPU ("fpv2_divd", fpv2_divd, CSKY_ISA_FEAT (CSKY_ISA_FPv2_DIVD))
> +
> +CSKY_FPU ("fpv3_hf",   fpv3_hf,   CSKY_ISA_FEAT (CSKY_ISA_FPv3_HF))
> +CSKY_FPU ("fpv3_hsf",  fpv3_hsf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_HSF))
> +CSKY_FPU ("fpv3_sdf",  fpv3_sdf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_SDF))
> +CSKY_FPU ("fpv3",      fpv3,      CSKY_ISA_FEAT (CSKY_ISA_FPv3))
>   #endif
> diff --git a/gcc/config/csky/csky_insn_fpu.md b/gcc/config/csky/csky_insn_fpu.md
> index c1e78af..e0d01ab 100644
> --- a/gcc/config/csky/csky_insn_fpu.md
> +++ b/gcc/config/csky/csky_insn_fpu.md
> @@ -18,528 +18,314 @@
>   ;; along with GCC; see the file COPYING3.  If not see
>   ;; <http://www.gnu.org/licenses/>.  */
>   
> -;; -------------------------------------------------------------------------
> -;; Float Abs instructions
> -;; -------------------------------------------------------------------------
> +(define_c_enum "unspec" [
> +  UNSPEC_FLOOR
> +  UNSPEC_CEIL
> +  UNSPEC_BTRUNC
> +  UNSPEC_RINT
> +])
>   
> -(define_insn "abssf2"
> -  [(set (match_operand:SF	  0 "register_operand" "=v,r")
> -	(abs:SF (match_operand:SF 1 "register_operand" "v, r")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "@
> -    fabss\t%0, %1
> -    bclri\t%0, %1, 31")
> +(define_c_enum "unspecv" [
> +  VUNSPEC_GET_FCR     ; Represent fetch of FCR content.
> +  VUNSPEC_SET_FCR     ; Represent assign of FCR content.
> +  VUNSPEC_INS_FCR     ; Represent insert of FCR content.
> +])
>   
> -(define_insn "absdf2"
> -  [(set (match_operand:DF	  0 "register_operand" "=v")
> -	(abs:DF (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fabsd\t%0, %1")
> +(define_mode_iterator F3ANY [HF SF DF])
> +(define_mode_attr f3t [(HF "16") (SF "32") (DF "64")])
>   
> +(define_mode_iterator SFDF [SF DF])
> +(define_mode_attr f2t [(SF "32") (DF "64")])
>   
> -;; -------------------------------------------------------------------------
> -;; Float Neg instructions
> -;; -------------------------------------------------------------------------
> +(define_code_iterator FCMPZ [ne ge lt gt le])
> +(define_code_attr zero_inst [(ne "nez") (ge "hsz") (lt "ltz") (gt "hz") (le "lsz")])
>   
> -(define_insn "negsf2"
> -  [(set (match_operand:SF	  0 "register_operand" "=v")
> -	(neg:SF (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnegs\t%0, %1")
> +(define_code_iterator FCMP [ne ge lt])
> +(define_code_attr reg_inst [(ne "ne") (ge "hs") (lt "lt")])
>   
> -(define_insn "negdf2"
> -  [(set (match_operand:DF	  0 "register_operand" "=v")
> -	(neg:DF (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnegd\t%0, %1")
> +(define_code_iterator FIX_SU [fix unsigned_fix])
> +(define_code_attr fixsuop [(fix "")  (unsigned_fix "uns")])
> +(define_code_attr fixsu   [(fix "s") (unsigned_fix "u")])
>   
> +(define_code_iterator FLOAT_SU [float unsigned_float])
> +(define_code_attr floatsuop [(float "")  (unsigned_float "uns")])
> +(define_code_attr floatsu   [(float "s") (unsigned_float "u")])
>   
> -;; -------------------------------------------------------------------------
> -;; Float Sqrt instructions
> -;; -------------------------------------------------------------------------
> +(define_int_iterator FRM  [UNSPEC_FLOOR
> +			   UNSPEC_CEIL UNSPEC_RINT])
>   
> -(define_insn "sqrtsf2"
> -  [(set (match_operand:SF	   0 "register_operand" "=v")
> -	(sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fsqrts\t%0, %1")
> +(define_int_iterator FRMF [UNSPEC_FLOOR
> +			   UNSPEC_CEIL UNSPEC_BTRUNC])
>   
> -(define_insn "sqrtdf2"
> -  [(set (match_operand:DF	   0 "register_operand" "=v")
> -	(sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_divd)"
> - "fsqrtd\t%0, %1")
> +(define_int_attr frm_pattern [(UNSPEC_FLOOR "floor")
> +			      (UNSPEC_CEIL "ceil")   (UNSPEC_BTRUNC "btrunc")
> +			      (UNSPEC_RINT "rint")])
> +
> +(define_int_attr rm [(UNSPEC_FLOOR ".rni")
> +		     (UNSPEC_CEIL ".rpi")  (UNSPEC_BTRUNC ".rz")
> +		     (UNSPEC_RINT "")])
>   
>   
>   ;; -------------------------------------------------------------------------
> -;; Float Add instructions
> +;; Float mov instructions
>   ;; -------------------------------------------------------------------------
>   
> -(define_insn "addsf3"
> -  [(set (match_operand:SF	   0 "register_operand" "=v")
> -	(plus:SF (match_operand:SF 1 "register_operand" "v")
> -		 (match_operand:SF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fadds\t%0, %1, %2")
> +(define_expand "movhf"
> +  [(set (match_operand:HF 0 "general_operand" "")
> +	(match_operand:HF 1 "general_operand" ""))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "
> +  {
> +    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
> +      {
> +	operands[1] = force_reg (HFmode, operands[1]);
> +      }
> +  }
> +")
> +
> +(define_expand "mov<mode>"
> +  [(set (match_operand:SFDF 0 "general_operand" "")
> +	(match_operand:SFDF 1 "general_operand" ""))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>)
> +   || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "
> +  {
> +    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
> +      {
> +	operands[1] = force_reg (<MODE>mode, operands[1]);
> +      }
> +  }
> +")
> +
> +;; Move float value with general register.
> +
> +(define_insn "*e2_movsf"
> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
> +       (match_operand:SF 1 "general_operand"      " b,r,m,mF,r"))]
> +  "CSKY_ISA_FEATURE (E2)
> +   && !CSKY_ISA_FEATURE (fpv2_sf)
> +   && !CSKY_ISA_FEATURE (fpv3_sf)"
> +  "* return csky_output_move (insn, operands, SFmode);"
> + [(set_attr "length" "2,4,4,4,4")
> +  (set_attr "type" "alu,alu,load,load,store")]
> +)
> +
> +(define_insn "*e2_movdf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
> +       (match_operand:DF 1 "general_operand"      " b,r,m,mF,r"))]
> +  "CSKY_ISA_FEATURE (E2)
> +   && !CSKY_ISA_FEATURE (fpv2_df)
> +   && !CSKY_ISA_FEATURE (fpv3_df)"
> +  "* return csky_output_movedouble (operands, DFmode);"
> + [(set_attr "length" "4,8,8,8,8")
> +  (set_attr "type" "alu,alu,load,load,store")]
> +)
>   
> -(define_insn "adddf3"
> -  [(set (match_operand:DF	   0 "register_operand" "=v")
> -	(plus:DF (match_operand:DF 1 "register_operand" "v")
> -		 (match_operand:DF 2 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_df)"
> - "faddd\t%0, %1, %2")
> +(define_insn "*e1_movsf"
> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
> +	(match_operand:SF 1 "general_operand"      " r,m,mF,r"))]
> +  "CSKY_ISA_FEATURE (E1)"
> +  "* return csky_output_ck801_move (insn, operands, SFmode);"
> +  [(set_attr "length" "2,4,4,4")
> +   (set_attr "type" "alu,load,load,store")]
> +)
>   
> +(define_insn "*e1_movdf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
> +	(match_operand:DF 1 "general_operand"      " r,m,mF,r"))]
> +  "CSKY_ISA_FEATURE (E1)"
> +  "* return csky_output_ck801_movedouble (operands, DFmode);"
> +  [(set_attr "length" "4,8,8,8")
> +   (set_attr "type" "alu,load,load,store")]
> +)
>   
>   ;; -------------------------------------------------------------------------
> -;; Float Sub instructions
> +;; Float Mul instructions
>   ;; -------------------------------------------------------------------------
>   
> -(define_insn "subsf3"
> -  [(set (match_operand:SF	    0 "register_operand" "=v")
> -	(minus:SF (match_operand:SF 1 "register_operand" "v")
> -		  (match_operand:SF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fsubs\t%0, %1, %2")
> +(define_expand "mulhf3"
> +  [(set (match_operand:HF	    0 "register_operand" "=v")
> +	(mult:HF (match_operand:HF   1 "register_operand" "v")
> +		 (match_operand:HF   2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
>   
> -(define_insn "subdf3"
> -  [(set (match_operand:DF	    0 "register_operand" "=v")
> -	(minus:DF (match_operand:DF 1 "register_operand" "v")
> -		  (match_operand:DF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fsubd\t%0, %1, %2")
> +(define_expand "mul<mode>3"
> +  [(set (match_operand:SFDF	    0 "register_operand" "=v")
> +	(mult:SFDF (match_operand:SFDF   1 "register_operand" "v")
> +		 (match_operand:SFDF   2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>)
> +  || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
>   
> +(define_expand "fma<mode>4"
> +  [(set (match_operand:F3ANY	    0 "register_operand" "=v")
> +	(fma:F3ANY (match_operand:F3ANY  1 "register_operand" "v")
> +		   (match_operand:F3ANY  2 "register_operand" "v")
> +		   (match_operand:F3ANY  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
>   
>   ;; -------------------------------------------------------------------------
> -;; Float Mul instructions
> +;; Float ADD SUB NEG ABS instructions
>   ;; -------------------------------------------------------------------------
>   
> -(define_insn "mulsf3"
> -  [(set (match_operand:SF	   0 "register_operand" "=v")
> -	(mult:SF (match_operand:SF 1 "register_operand" "v")
> -		 (match_operand:SF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fmuls\t%0, %1, %2")
> -
> -(define_insn "muldf3"
> -  [(set (match_operand:DF	   0 "register_operand" "=v")
> -	(mult:DF (match_operand:DF 1 "register_operand" "v")
> -		 (match_operand:DF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fmuld\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_nmulsf3_1"
> -  [(set (match_operand:SF		   0 "register_operand" "=v")
> -	(mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
> -		 (match_operand:SF	   2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
> -  "fnmuls\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_nmulsf3_2"
> -  [(set (match_operand:SF		   0 "register_operand" "=v")
> -	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> -			 (match_operand:SF 2 "register_operand" "v"))))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnmuls\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_nmuldf3_1"
> -  [(set (match_operand:DF		   0 "register_operand" "=v")
> -	(mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
> -		 (match_operand:DF	   2 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
> - "fnmuld\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_nmuldf3_2"
> -  [(set (match_operand:DF		   0 "register_operand" "=v")
> -	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> -			 (match_operand:DF 2 "register_operand" "v"))))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnmuld\t%0, %1, %2")
> +(define_expand "addhf3"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(plus:HF (match_operand:HF  1 "register_operand" "")
> +		 (match_operand:HF  2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
> +
> +(define_expand "add<mode>3"
> +  [(set (match_operand:SFDF	     0 "register_operand" "")
> +	(plus:SFDF (match_operand:SFDF  1 "register_operand" "")
> +		   (match_operand:SFDF  2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
> +(define_expand "subhf3"
> +  [(set (match_operand:HF	    0 "register_operand" "")
> +	(minus:HF (match_operand:HF  1 "register_operand" "")
> +		  (match_operand:HF  2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
>   
> -;; -------------------------------------------------------------------------
> -;; Float Div instructions
> -;; -------------------------------------------------------------------------
> +(define_expand "sub<mode>3"
> +  [(set (match_operand:SFDF	      0 "register_operand" "")
> +	(minus:SFDF (match_operand:SFDF  1 "register_operand" "")
> +		    (match_operand:SFDF  2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
> -(define_expand "divsf3"
> -  [(set (match_operand:SF	  0 "register_operand" "")
> -	(div:SF (match_operand:SF 1 "csky_arith_float1_operand" "")
> -		(match_operand:SF 2 "register_operand" "")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "")
> +(define_expand "abshf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(abs:HF (match_operand:HF   1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
>   
> -(define_insn "*fpuv2_divsf3"
> -  [(set (match_operand:SF	  0 "register_operand" "=v")
> -	(div:SF (match_operand:SF 1 "register_operand" "v")
> -		(match_operand:SF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fdivs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_1_divsf3"
> -  [(set (match_operand:SF	  0 "register_operand"		"=v")
> -	(div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
> -		(match_operand:SF 2 "register_operand"		"v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "frecips\t%0, %2")
> -
> -
> -(define_expand "divdf3"
> -  [(set (match_operand:DF 0 "register_operand" "")
> -	(div:DF (match_operand:DF 1 "csky_arith_float1_operand" "")
> -		(match_operand:DF 2 "register_operand" "")))]
> -  "CSKY_ISA_FEATURE (fpv2_divd)"
> -  "")
> +(define_expand "abs<mode>2"
> +  [(set (match_operand:SFDF	     0 "register_operand" "")
> +	(abs:SFDF (match_operand:SFDF   1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
> -(define_insn "*fpuv2_divdf3"
> -  [(set (match_operand:DF	  0 "register_operand" "=v")
> -	(div:DF (match_operand:DF 1 "register_operand" "v")
> -		(match_operand:DF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_divd)"
> -  "fdivd\t%0, %1, %2")
> +(define_expand "neghf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(neg:HF (match_operand:HF   1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
>   
> -(define_insn "*fpuv2_1_divdf3"
> -  [(set (match_operand:DF	  0 "register_operand"		"=v")
> -	(div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
> -		(match_operand:DF 2 "register_operand"		"v")))]
> -  "CSKY_ISA_FEATURE (fpv2_divd)"
> -  "frecipd\t%0, %2")
> +(define_expand "neg<mode>2"
> +  [(set (match_operand:SFDF	   0 "register_operand" "")
> +	(neg:SFDF (match_operand:SFDF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
> +(define_expand "sqrthf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(sqrt:HF (match_operand:HF  1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
> +
> +(define_expand "sqrt<mode>2"
> +  [(set (match_operand:SFDF	    0 "register_operand" "")
> +	(sqrt:SFDF (match_operand:SFDF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
>   ;; -------------------------------------------------------------------------
> -;; Float add(sub) with mult instructions
> +;; Float div instructions
>   ;; -------------------------------------------------------------------------
>   
> -;; vrz <= vrz + vrx * vry
> -(define_insn "*fpuv2_fmacs"
> -  [(set (match_operand:SF		    0 "register_operand" "=v")
> -	(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> -			  (match_operand:SF 2 "register_operand" "v"))
> -		 (match_operand:SF	    3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fmacs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fmacd"
> -  [(set (match_operand:DF		    0 "register_operand" "=v")
> -	(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> -			  (match_operand:DF 2 "register_operand" "v"))
> -		 (match_operand:DF	    3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fmacd\t%0, %1, %2")
> -
> -;; vrz <= vrz - vrx * vry
> -(define_insn "*fpuv2_fnmacs"
> -  [(set (match_operand:SF		     0 "register_operand" "=v")
> -	(minus:SF (match_operand:SF	     1 "register_operand" "0")
> -		  (mult:SF (match_operand:SF 2 "register_operand" "v")
> -			   (match_operand:SF 3 "register_operand" "v"))))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnmacs\t%0, %2, %3")
> -
> -(define_insn "*fpuv2_fnmacd"
> -  [(set (match_operand:DF		     0 "register_operand" "=v")
> -	(minus:DF (match_operand:DF	     1 "register_operand" "0")
> -		  (mult:DF (match_operand:DF 2 "register_operand" "v")
> -			   (match_operand:DF 3 "register_operand" "v"))))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnmacd\t%0, %2, %3")
> -
> -;; vrz <= vrx * vry - vrz
> -(define_insn "*fpuv2_fmscs"
> -  [(set (match_operand:SF		     0 "register_operand" "=v")
> -	(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> -			   (match_operand:SF 2 "register_operand" "v"))
> -		  (match_operand:SF	     3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fmscs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fmscd"
> -  [(set (match_operand:DF 0 "register_operand" "=v")
> -	(minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> -			   (match_operand:DF 2 "register_operand" "v"))
> -		  (match_operand:DF 3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fmscd\t%0, %1, %2")
> -
> -;; vrz = - (vrz + vrx * vry)
> -(define_insn "*fpuv2_fnmscs_1"
> -  [(set (match_operand:SF			     0 "register_operand" "=v")
> -	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
> -			   (match_operand:SF	     2 "register_operand" "v"))
> -		  (match_operand:SF		     3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnmscs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fnmscs_2"
> -  [(set (match_operand:SF			    0 "register_operand" "=v")
> -	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> -				  (match_operand:SF 2 "register_operand" "v"))
> -			 (match_operand:SF	    3 "register_operand" "0"))))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnmscs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fnmscd_1"
> -  [(set (match_operand:DF 0 "register_operand" "=v")
> -	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
> -			   (match_operand:DF 2 "register_operand" "v"))
> -		  (match_operand:DF 3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnmscd\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fnmscd_2"
> -  [(set (match_operand:DF 0 "register_operand" "=v")
> -	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> -				  (match_operand:DF 2 "register_operand" "v"))
> -			 (match_operand:DF 3 "register_operand" "0"))))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnmscd\t%0, %1, %2")
> +(define_expand "div<mode>3"
> +  [(set (match_operand:SFDF	   0 "register_operand" "")
> +	(div:SFDF (match_operand:SFDF 1 "csky_arith_float1_operand" "")
> +		  (match_operand:SFDF 2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
>   
> +(define_expand "divhf3"
> + [(set (match_operand:HF 0 "register_operand" "")
> +       (div:HF (match_operand:HF 1 "csky_arith_float1_operand" "")
> +	       (match_operand:HF 2 "register_operand" "")))]
> + "CSKY_ISA_FEATURE(fpv3_hf)"
> + "")
>   
>   ;; -------------------------------------------------------------------------
>   ;; Float compare instructions
>   ;; -------------------------------------------------------------------------
>   
> -(define_expand "cbranchsf4"
> +(define_expand "cbranch<mode>4"
>     [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
> -			     [(match_operand:SF 1 "register_operand")
> -			      (match_operand:SF 2 "csky_compare_operand_float")])
> +			    [(match_operand:SFDF 1 "register_operand")
> +			     (match_operand:SFDF 2 "csky_compare_operand_float")])
>   			   (label_ref (match_operand 3 ""))
>   			   (pc)))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "
> -  {
> -    enum rtx_code code = GET_CODE (operands[0]);
> -    bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
> +"CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +"{
> +  enum rtx_code code = GET_CODE (operands[0]);
> +  bool invert;
>   
> -    if (invert)
> -      emit_jump_insn (gen_csky_jbf (operands[3]));
> -    else
> -      emit_jump_insn (gen_csky_jbt (operands[3]));
> +  invert = csky_emit_compare_float (code, operands[1], operands[2]);
>   
> -    DONE;
> -  }")
> -
> -(define_insn "*fpuv2_unordered"
> -  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
> -				  (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpuos\t%0, %1")
> -
> -(define_insn "*fpuv2_unordered_zero"
> -  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
> -				  (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpuos\t%0, %0")
> -
> -(define_insn "*fpuv2_ne"
> -  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpnes\t%0, %1")
> -
> -(define_insn "*fpuv2_gt"
> -  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmplts\t%1, %0")
> -
> -(define_insn "*fpuv2_ge"
> -  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_sf)"
> - "fcmphss\t%0, %1")
> -
> -(define_insn "*fpuv2_lt"
> -  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmplts\t%0, %1")
> -
> -(define_insn "*fpuv2_le"
> -  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_sf)"
> - "fcmphss\t%1, %0")
> -
> -(define_insn "*fpuv2_gez"
> -  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand"	   "v")
> -			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpzhss\t%0")
> -
> -(define_insn "*fpuv2_nez"
> -  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand"	   "v")
> -			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpznes\t%0")
> -
> -
> -(define_expand "cbranchdf4"
> -  [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
> -			     [(match_operand:DF 1 "register_operand")
> -			      (match_operand:DF 2 "csky_compare_operand_float")])
> -			   (label_ref (match_operand 3 ""))
> -			   (pc)))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "
> -  {
> -    enum rtx_code code = GET_CODE (operands[0]);
> -    bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
> +  if (invert)
> +    emit_jump_insn (gen_csky_jbf (operands[3]));
> +  else
> +    emit_jump_insn (gen_csky_jbt (operands[3]));
>   
> -    if (invert)
> -      emit_jump_insn (gen_csky_jbf (operands[3]));
> -    else
> -      emit_jump_insn (gen_csky_jbt (operands[3]));
> +  DONE;
>   
> -    DONE;
>   }")
>   
> -(define_insn "*fpuv2_dunordered"
> -  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
> -				  (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpuod\t%0, %1")
> -
> -(define_insn "*fpuv2_dunordered_zero"
> -  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
> -				  (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpuod\t%0, %0")
> -
> -(define_insn "*fpuv2_dne"
> -  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpned\t%0, %1")
> -
> -(define_insn "*fpuv2_dgt"
> -  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpltd\t%1, %0")
> -
> -(define_insn "*fpuv2_dge"
> -  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmphsd\t%0, %1")
> -
> -(define_insn "*fpuv2_dlt"
> -  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_df)"
> - "fcmpltd\t%0, %1")
> -
> -(define_insn "*fpuv2_dle"
> -  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmphsd\t%1, %0")
> -
> -(define_insn "*fpuv2_dgez"
> -  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand"	   "v")
> -			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> - "CSKY_ISA_FEATURE (fpv2_df)"
> - "fcmpzhsd\t%0")
> -
> -(define_insn "*fpuv2_dnez"
> -  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand"	   "v")
> -			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpzned\t%0")
> +(define_expand "cbranchhf4"
> +  [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
> +			    [(match_operand:HF 1 "register_operand")
> +			     (match_operand:HF 2 "csky_compare_operand_float")])
> +			   (label_ref (match_operand 3 ""))
> +			   (pc)))]
> +"CSKY_ISA_FEATURE(fpv3_hf)"
> +"{
> +  enum rtx_code code = GET_CODE (operands[0]);
> +  bool invert;
>   
> +  invert = csky_emit_compare_float (code, operands[1], operands[2]);
>   
> -;; -------------------------------------------------------------------------
> -;; Float convert instructions
> -;; -------------------------------------------------------------------------
> +  if (invert)
> +    emit_jump_insn (gen_csky_jbf (operands[3]));
> +  else
> +    emit_jump_insn (gen_csky_jbt (operands[3]));
>   
> -;; DF <- SF
> -(define_insn "extendsfdf2"
> -  [(set (match_operand:DF		   0 "register_operand" "=v")
> -	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fstod\t%0, %1")
> -
> -;; SF <- DF
> -(define_insn "truncdfsf2"
> -  [(set (match_operand:SF		     0 "register_operand" "=v")
> -	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fdtos\t%0, %1")
> -
> -;; SF <- SI
> -(define_insn "floatsisf2"
> -  [(set (match_operand:SF	    0 "register_operand" "=v")
> -	(float:SF (match_operand:SI 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fsitos\t%0, %1")
> -
> -;; DF <- SI
> -(define_insn "floatsidf2"
> -  [(set (match_operand:DF	    0 "register_operand" "=v")
> -	(float:DF (match_operand:SI 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fsitod\t%0, %1")
> -
> -;; SF <- unsigned SI
> -(define_insn "floatunssisf2"
> -  [(set (match_operand:SF		     0 "register_operand" "=v")
> -	(unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fuitos\t%0, %1")
> -
> -;; DF <- unsigned SI
> -(define_insn "floatunssidf2"
> -  [(set (match_operand:DF		     0 "register_operand" "=v")
> -	(unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fuitod\t%0, %1")
> -
> -;; SI <- SF
> -(define_insn "fix_truncsfsi2"
> -  [(set (match_operand:SI	  0 "register_operand" "=v")
> -	(fix:SI (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fstosi.rz\t%0, %1")
> -
> -;; SI <- DF
> -(define_insn "fix_truncdfsi2"
> -  [(set (match_operand:SI	  0 "register_operand" "=v")
> -	(fix:SI (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fdtosi.rz\t%0, %1")
> -
> -;; unsigned SI <- SF
> -(define_insn "fixuns_truncsfsi2"
> -  [(set (match_operand:SI		   0 "register_operand" "=v")
> -	(unsigned_fix:SI (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fstoui.rz\t%0, %1")
> -
> -;; unsigned SI <- DF
> -(define_insn "fixuns_truncdfsi2"
> -  [(set (match_operand:SI		   0 "register_operand" "=v")
> -	(unsigned_fix:SI (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fdtoui.rz\t%0, %1")
> +  DONE;
>   
> +}")
>   
>   ;; -------------------------------------------------------------------------
> -;; Float mov instructions
> +;; Instructions for float cstore
>   ;; -------------------------------------------------------------------------
>   
> -;; Note:  movsf and movdf patterns are in csky.md.
> -
> -;; cstore SF
> -(define_expand "cstoresf4"
> +(define_expand "cstore<mode>4"
>     [(set (match_operand:SI 0 "register_operand" "")
> -	(match_operator	  1 "ordered_comparison_operator"
> -	  [(match_operand:SF 2 "register_operand" "")
> -	   (match_operand:SF 3 "csky_compare_operand_float" "")]))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "
> -  {
> -    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
> -					   operands[2], operands[3]);
> -    if (invert)
> +	(match_operator   1 "csky_float_comparison_operator"
> +	  [(match_operand:SFDF 2 "register_operand" "")
> +	   (match_operand:SFDF 3 "csky_compare_operand_float" "")]))]
> +  "CSKY_ISA_FEATURE (fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "{
> +    bool invert;
> +
> +    invert = csky_emit_compare_float (GET_CODE (operands[1]),
> +				 operands[2], operands[3]);
> +    if(invert)
>         emit_insn (gen_mvcv (operands[0]));
>       else
>         emit_insn (gen_mvc (operands[0]));
> @@ -547,21 +333,91 @@
>     }"
>   )
>   
> -;; cstore DF
> -(define_expand "cstoredf4"
> +(define_expand "cstorehf4"
>     [(set (match_operand:SI 0 "register_operand" "")
> -	(match_operator 1 "ordered_comparison_operator"
> -	  [(match_operand:DF 2 "register_operand" "")
> -	   (match_operand:DF 3 "csky_compare_operand_float" "")]))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "
> -  {
> -    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
> -					   operands[2], operands[3]);
> -    if (invert)
> +	(match_operator   1 "csky_float_comparison_operator"
> +	  [(match_operand:HF 2 "register_operand" "")
> +	   (match_operand:HF 3 "csky_compare_operand_float" "")]))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "{
> +    bool invert;
> +
> +    invert = csky_emit_compare_float (GET_CODE (operands[1]),
> +				 operands[2], operands[3]);
> +    if(invert)
>         emit_insn (gen_mvcv (operands[0]));
>       else
>         emit_insn (gen_mvc (operands[0]));
>       DONE;
>     }"
>   )
> +
> +;; -------------------------------------------------------------------------
> +;; Float convert instructions
> +;; -------------------------------------------------------------------------
> +
> +;; SF <- HF
> +(define_expand "extendhfsf2"
> +  [(set (match_operand:SF		  0 "register_operand" "")
> +	(float_extend:SF (match_operand:HF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; HF <- SF
> +(define_expand "truncsfhf2"
> +  [(set (match_operand:HF		     0 "register_operand" "")
> +	(float_truncate:HF (match_operand:SF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; DF <- SF
> +(define_expand "extendsfdf2"
> +  [(set (match_operand:DF		  0 "register_operand" "")
> +	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
> +  "")
> +
> +;; SF <- DF
> +(define_expand "truncdfsf2"
> +  [(set (match_operand:SF		    0 "register_operand" "")
> +	(float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
> +  "")
> +
> +;; HF <- unsigned SI,SI
> +(define_expand "float<floatsuop>sihf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(FLOAT_SU:HF (match_operand:SI 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; DF,SF <- unsigned SI,SI
> +(define_expand "float<floatsuop>si<mode>2"
> +  [(set (match_operand:SFDF		    0 "register_operand" "")
> +	(FLOAT_SU:SFDF (match_operand:SI 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
> +
> +;; HF <- unsigned HI,HI
> +(define_expand "float<floatsuop>hihf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(FLOAT_SU:HF (match_operand:HI 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; unsigned SI,SI <- HF
> +(define_expand "fix<fixsuop>_trunchfsi2"
> +  [(set (match_operand:SI	    0 "register_operand" "")
> +	(FIX_SU:SI (fix:HF (match_operand:HF 1 "register_operand" ""))))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; unsigned SI,SI <- DF,SF
> +(define_expand "fix<fixsuop>_trunc<mode>si2"
> +  [(set (match_operand:SI	    0 "register_operand" "")
> +	(FIX_SU:SI (fix:SFDF (match_operand:SFDF 1 "register_operand" ""))))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
> +
> +(include "csky_insn_fpuv3.md")
> +(include "csky_insn_fpuv2.md")
> diff --git a/gcc/config/csky/csky_insn_fpuv2.md b/gcc/config/csky/csky_insn_fpuv2.md
> new file mode 100644
> index 0000000..0a680f8
> --- /dev/null
> +++ b/gcc/config/csky/csky_insn_fpuv2.md
> @@ -0,0 +1,470 @@
> +
> +;; -------------------------------------------------------------------------
> +;; Float Abs instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_abssf2"
> +  [(set (match_operand:SF	 0 "register_operand" "=v,a,r")
> +	(abs:SF (match_operand:SF 1 "register_operand" "v, 0,r")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "@
> +    fabss\t%0, %1
> +    bclri\t%0, %1, 31
> +    bclri\t%0, %1, 31"
> +  [(set_attr "length" "4,2,4")])
> +
> +(define_insn "*fpuv2_absdf2"
> +  [(set (match_operand:DF	 0 "register_operand" "=v")
> +	(abs:DF (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fabsd\t%0, %1")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Neg instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_negsf2"
> +  [(set (match_operand:SF	 0 "register_operand" "=v")
> +	(neg:SF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnegs\t%0, %1")
> +
> +(define_insn "*fpuv2_negdf2"
> +  [(set (match_operand:DF	 0 "register_operand" "=v")
> +	(neg:DF (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnegd\t%0, %1")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Sqrt instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_sqrtsf2"
> +  [(set (match_operand:SF	  0 "register_operand" "=v")
> +	(sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fsqrts\t%0, %1")
> +
> +(define_insn "*fpuv2_sqrtdf2"
> +  [(set (match_operand:DF	  0 "register_operand" "=v")
> +	(sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_divd)"
> + "fsqrtd\t%0, %1")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Add instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_addsf3"
> +  [(set (match_operand:SF	  0 "register_operand" "=v")
> +	(plus:SF (match_operand:SF 1 "register_operand" "v")
> +		 (match_operand:SF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fadds\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_adddf3"
> +  [(set (match_operand:DF	  0 "register_operand" "=v")
> +	(plus:DF (match_operand:DF 1 "register_operand" "v")
> +		 (match_operand:DF 2 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_df)"
> + "faddd\t%0, %1, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Sub instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_subsf3"
> +  [(set (match_operand:SF	   0 "register_operand" "=v")
> +	(minus:SF (match_operand:SF 1 "register_operand" "v")
> +		  (match_operand:SF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fsubs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_subdf3"
> +  [(set (match_operand:DF	   0 "register_operand" "=v")
> +	(minus:DF (match_operand:DF 1 "register_operand" "v")
> +		  (match_operand:DF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fsubd\t%0, %1, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Mul instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv2_mulsf3"
> +  [(set (match_operand:SF	  0 "register_operand" "=v")
> +	(mult:SF (match_operand:SF 1 "register_operand" "v")
> +		 (match_operand:SF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fmuls\t%0, %1, %2")
> +
> +(define_insn "*fpv2_muldf3"
> +  [(set (match_operand:DF	  0 "register_operand" "=v")
> +	(mult:DF (match_operand:DF 1 "register_operand" "v")
> +		 (match_operand:DF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fmuld\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_nmulsf3_1"
> +  [(set (match_operand:SF		  0 "register_operand" "=v")
> +	(mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
> +		 (match_operand:SF	 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
> +  "fnmuls\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_nmulsf3_2"
> +  [(set (match_operand:SF		  0 "register_operand" "=v")
> +	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> +			 (match_operand:SF 2 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnmuls\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_nmuldf3_1"
> +  [(set (match_operand:DF		  0 "register_operand" "=v")
> +	(mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
> +		 (match_operand:DF	 2 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
> + "fnmuld\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_nmuldf3_2"
> +  [(set (match_operand:DF		  0 "register_operand" "=v")
> +	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> +			 (match_operand:DF 2 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnmuld\t%0, %1, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Div instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_divsf3"
> +  [(set (match_operand:SF	 0 "register_operand" "=v")
> +	(div:SF (match_operand:SF 1 "register_operand" "v")
> +		(match_operand:SF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fdivs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_1_divsf3"
> +  [(set (match_operand:SF	 0 "register_operand"	  "=v")
> +	(div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
> +		(match_operand:SF 2 "register_operand"	  "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "frecips\t%0, %2")
> +
> +(define_insn "*fpuv2_divdf3"
> +  [(set (match_operand:DF	 0 "register_operand" "=v")
> +	(div:DF (match_operand:DF 1 "register_operand" "v")
> +		(match_operand:DF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_divd)"
> +  "fdivd\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_1_divdf3"
> +  [(set (match_operand:DF	 0 "register_operand"	  "=v")
> +	(div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
> +		(match_operand:DF 2 "register_operand"	  "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_divd)"
> +  "frecipd\t%0, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float add(sub) with mult instructions
> +;; -------------------------------------------------------------------------
> +
> +;; vrz <= vrz + vrx * vry
> +(define_insn "*fpuv2_fmacs"
> +  [(set (match_operand:SF		   0 "register_operand" "=v")
> +	(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> +			  (match_operand:SF 2 "register_operand" "v"))
> +		 (match_operand:SF	  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fmacs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fmacd"
> +  [(set (match_operand:DF		   0 "register_operand" "=v")
> +	(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> +			  (match_operand:DF 2 "register_operand" "v"))
> +		 (match_operand:DF	  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fmacd\t%0, %1, %2")
> +
> +;; vrz <= vrz - vrx * vry
> +(define_insn "*fpuv2_fnmacs"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(minus:SF (match_operand:SF	  1 "register_operand" "0")
> +		  (mult:SF (match_operand:SF 2 "register_operand" "v")
> +			   (match_operand:SF 3 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnmacs\t%0, %2, %3")
> +
> +(define_insn "*fpuv2_fnmacd"
> +  [(set (match_operand:DF		    0 "register_operand" "=v")
> +	(minus:DF (match_operand:DF	  1 "register_operand" "0")
> +		  (mult:DF (match_operand:DF 2 "register_operand" "v")
> +			   (match_operand:DF 3 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnmacd\t%0, %2, %3")
> +
> +;; vrz <= vrx * vry - vrz
> +(define_insn "*fpuv2_fmscs"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> +			   (match_operand:SF 2 "register_operand" "v"))
> +		  (match_operand:SF	  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fmscs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fmscd"
> +  [(set (match_operand:DF 0 "register_operand" "=v")
> +	(minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> +			   (match_operand:DF 2 "register_operand" "v"))
> +		  (match_operand:DF 3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fmscd\t%0, %1, %2")
> +
> +;; vrz = - (vrz + vrx * vry)
> +(define_insn "*fpuv2_fnmscs_1"
> +  [(set (match_operand:SF			    0 "register_operand" "=v")
> +	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
> +			   (match_operand:SF	 2 "register_operand" "v"))
> +		  (match_operand:SF		  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnmscs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fnmscs_2"
> +  [(set (match_operand:SF			   0 "register_operand" "=v")
> +	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> +				  (match_operand:SF 2 "register_operand" "v"))
> +			 (match_operand:SF	  3 "register_operand" "0"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnmscs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fnmscd_1"
> +  [(set (match_operand:DF 0 "register_operand" "=v")
> +	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
> +			   (match_operand:DF 2 "register_operand" "v"))
> +		  (match_operand:DF 3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnmscd\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fnmscd_2"
> +  [(set (match_operand:DF 0 "register_operand" "=v")
> +	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> +				  (match_operand:DF 2 "register_operand" "v"))
> +			 (match_operand:DF 3 "register_operand" "0"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnmscd\t%0, %1, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float compare instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_unordered"
> +  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
> +				  (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpuos\t%0, %1")
> +
> +(define_insn "*fpuv2_unordered_zero"
> +  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
> +				  (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpuos\t%0, %0")
> +
> +(define_insn "*fpuv2_ne"
> +  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpnes\t%0, %1")
> +
> +(define_insn "*fpuv2_gt"
> +  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmplts\t%1, %0")
> +
> +(define_insn "*fpuv2_ge"
> +  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_sf)"
> + "fcmphss\t%0, %1")
> +
> +(define_insn "*fpuv2_lt"
> +  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmplts\t%0, %1")
> +
> +(define_insn "*fpuv2_le"
> +  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_sf)"
> + "fcmphss\t%1, %0")
> +
> +(define_insn "*fpuv2_gez"
> +  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand"	  "v")
> +			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpzhss\t%0")
> +
> +(define_insn "*fpuv2_nez"
> +  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand"	  "v")
> +			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpznes\t%0")
> +
> +(define_insn "*fpuv2_dunordered"
> +  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
> +				  (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpuod\t%0, %1")
> +
> +(define_insn "*fpuv2_dunordered_zero"
> +  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
> +				  (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpuod\t%0, %0")
> +
> +(define_insn "*fpuv2_dne"
> +  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpned\t%0, %1")
> +
> +(define_insn "*fpuv2_dgt"
> +  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpltd\t%1, %0")
> +
> +(define_insn "*fpuv2_dge"
> +  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmphsd\t%0, %1")
> +
> +(define_insn "*fpuv2_dlt"
> +  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_df)"
> + "fcmpltd\t%0, %1")
> +
> +(define_insn "*fpuv2_dle"
> +  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmphsd\t%1, %0")
> +
> +(define_insn "*fpuv2_dgez"
> +  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand"	  "v")
> +			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> + "CSKY_ISA_FEATURE (fpv2_df)"
> + "fcmpzhsd\t%0")
> +
> +(define_insn "*fpuv2_dnez"
> +  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand"	  "v")
> +			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpzned\t%0")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float convert instructions
> +;; -------------------------------------------------------------------------
> +
> +;; DF <- SF
> +(define_insn "*fpuv2_extendsfdf2"
> +  [(set (match_operand:DF		  0 "register_operand" "=v")
> +	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fstod\t%0, %1")
> +
> +;; SF <- DF
> +(define_insn "*fpuv2_truncdfsf2"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fdtos\t%0, %1")
> +
> +;; SF <- SI
> +(define_insn "*fpuv2_floatsisf2"
> +  [(set (match_operand:SF	   0 "register_operand" "=v")
> +	(float:SF (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fsitos\t%0, %1")
> +
> +;; DF <- SI
> +(define_insn "*fpuv2_floatsidf2"
> +  [(set (match_operand:DF	   0 "register_operand" "=v")
> +	(float:DF (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fsitod\t%0, %1")
> +
> +;; SF <- unsigned SI
> +(define_insn "*fpuv2_floatunssisf2"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fuitos\t%0, %1")
> +
> +;; DF <- unsigned SI
> +(define_insn "*fpuv2_floatunssidf2"
> +  [(set (match_operand:DF		    0 "register_operand" "=v")
> +	(unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fuitod\t%0, %1")
> +
> +;; SI <- SF
> +(define_insn "*fpuv2_fix_truncsfsi2"
> +  [(set (match_operand:SI	 0 "register_operand" "=v")
> +	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fstosi.rz\t%0, %1")
> +
> +;; SI <- DF
> +(define_insn "*fpuv2_fix_truncdfsi2"
> +  [(set (match_operand:SI	 0 "register_operand" "=v")
> +	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fdtosi.rz\t%0, %1")
> +
> +;; unsigned SI <- SF
> +(define_insn "*fpuv2_fixuns_truncsfsi2"
> +  [(set (match_operand:SI		  0 "register_operand" "=v")
> +	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fstoui.rz\t%0, %1")
> +
> +;; unsigned SI <- DF
> +(define_insn "*fpuv2_fixuns_truncdfsi2"
> +  [(set (match_operand:SI		  0 "register_operand" "=v")
> +	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fdtoui.rz\t%0, %1")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float mov instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_movsf"
> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r, r,m,v,r,Q,v,v,v")
> +	(match_operand:SF 1 "general_operand"      " r,m,mF,r,r,v,v,Q,v,W"))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "* return csky_output_move(insn, operands, SFmode);"
> +)
> +
> +(define_insn "*fpuv2_movdf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, r,m, v,?r,Q,v,v,v")
> +	(match_operand:DF 1 "general_operand"      " r,m,mF,r,?r, v,v,Q,v,m"))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "* return csky_output_movedouble(operands, DFmode);"
> +  [(set (attr "length")
> +	(symbol_ref "csky_get_movedouble_length (operands)"))]
> +)
> diff --git a/gcc/config/csky/csky_insn_fpuv3.md b/gcc/config/csky/csky_insn_fpuv3.md
> new file mode 100644
> index 0000000..053673c
> --- /dev/null
> +++ b/gcc/config/csky/csky_insn_fpuv3.md
> @@ -0,0 +1,497 @@
> +
> +(define_c_enum "unspec" [
> +  UNSPEC_MAXNM_F3
> +  UNSPEC_MINNM_F3
> +])
> +
> +;; -------------------------------------------------------------------------
> +;; Float mov instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_movhf"
> +  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v, v")
> +	(match_operand:HF 1 "general_operand"      " r,F,r,v,r,m,v,Q,v,W,Dv"))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "*
> +  switch (which_alternative)
> +    {
> +    case 2:
> +      return \"fmtvr.16\\t%0, %1\";
> +    case 3:
> +      return \"fmfvr.16\\t%0, %1\";
> +    case 6:
> +    case 7:
> +    case 9:
> +      return fpuv3_output_move(operands);
> +    case 8:
> +      return \"fmov.16\\t%0, %1\";
> +    case 10:
> +      return \"fmovi.16\\t%0, %1\";
> +    case 1:
> +      {
> +	long bits;
> +	rtx ops[4];
> +
> +	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), HFmode);
> +	ops[0] = operands[0];
> +	ops[1] = GEN_INT (bits);
> +
> +	output_asm_insn (\"lrw\\t%0, %1\", ops);
> +	return \"\";
> +      }
> +    default:
> +      return csky_output_move(insn, operands, HFmode);
> +    }
> +  "
> +)
> +
> +(define_insn "*fpv3_movsf"
> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r, r,m,v,r,Q,v,v,v, v")
> +	(match_operand:SF 1 "general_operand"      " r,m,mF,r,r,v,v,Q,v,W,Dv"))]
> +  "CSKY_ISA_FEATURE(fpv3_sf)"
> +  "*
> +  switch (which_alternative)
> +    {
> +    case 4:
> +      return \"fmtvr.32.1\\t%0, %1\";
> +    case 5:
> +      return \"fmfvr.32.1\\t%0, %1\";
> +    case 6:
> +    case 7:
> +    case 9:
> +      return fpuv3_output_move(operands);
> +    case 8:
> +      return \"fmov.32\\t%0, %1\";
> +    case 10:
> +      return \"fmovi.32\\t%0, %1\";
> +    default:
> +      return csky_output_move(insn, operands, SFmode);
> +    }
> +  "
> +)
> +
> +(define_insn "*fpv3_movdf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, r,m,v,?r,Q,v,v,v, v")
> +	(match_operand:DF 1 "general_operand"      " r,m,mF,r,?r,v,v,Q,v,m,Dv"))]
> +  "CSKY_ISA_FEATURE(fpv3_df)"
> +  "*
> +  switch (which_alternative)
> +    {
> +    case 4:
> +      if (TARGET_BIG_ENDIAN)
> +	return \"fmtvr.64\\t%0, %R1, %1\";
> +      return \"fmtvr.64\\t%0, %1, %R1\";
> +    case 5:
> +      if (TARGET_BIG_ENDIAN)
> +	return \"fmfvr.64\\t%R0, %0, %1\";
> +      return \"fmfvr.64\\t%0, %R0, %1\";
> +    case 6:
> +    case 7:
> +    case 9:
> +      return fpuv3_output_move(operands);
> +    case 8:
> +      return \"fmov.64\\t%0, %1\";
> +    case 10:
> +      return \"fmovi.64\\t%0, %1\";
> +    default:
> +      return csky_output_movedouble(operands, DFmode);
> +    }
> +  "
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float Mul instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_mul<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +		    (match_operand:F3ANY  2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fmul.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float Muladd and mulsub instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_mula<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "+v")
> +	(plus:F3ANY (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +				(match_operand:F3ANY  2 "register_operand" " v"))
> +		    (match_dup 0)))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fmula.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_muls<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "+v")
> +	(minus:F3ANY (match_dup 0)
> +		     (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +				 (match_operand:F3ANY  2 "register_operand" " v"))))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fmuls.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float fmula/fmuls/fnmula/fnmuls instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_fmuls_<mode>4"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(fma:F3ANY (neg:F3ANY (match_operand:F3ANY  1 "register_operand" "v"))
> +		   (match_operand:F3ANY   2 "register_operand" "v")
> +		   (match_operand:F3ANY   3 "register_operand"  "0")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "ffmuls.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_fmula_<mode>4"
> +  [(set (match_operand:F3ANY	    0 "register_operand" "=v")
> +	(fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
> +		   (match_operand:F3ANY 2 "register_operand" " v")
> +		   (match_operand:F3ANY 3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "ffmula.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_fnmula_<mode>4"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(neg: F3ANY (fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +			       (match_operand:F3ANY  2 "register_operand" " v")
> +			       (match_operand:F3ANY  3 "register_operand" "0"))))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "ffnmula.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_fnmuls_<mode>4"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +		   (match_operand:F3ANY  2 "register_operand" " v")
> +		   (neg:F3ANY (match_operand:F3ANY  3 "register_operand" "0"))))]
> +  "CSKY_ISA_FEATURE(fpv3_sf)"
> +  "ffnmuls.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float div/recipe/sqrt instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_div<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(div:F3ANY (match_operand:F3ANY   1 "register_operand" " v")
> +		   (match_operand:F3ANY   2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fdiv.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_recip<mode>3"
> +  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
> +	(div:F3ANY (match_operand:F3ANY  1 "csky_const_float1_operand" " i")
> +		   (match_operand:F3ANY  2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "frecip.<f3t>\t%0, %2"
> +)
> +
> +(define_insn "*fpv3_sqrt<mode>2"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(sqrt:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fsqrt.<f3t>\t%0, %1"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float fmax/fmin instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "fmax<mode>3"
> +  [(set (match_operand:F3ANY		 0 "register_operand" "=v")
> +	(unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
> +		       (match_operand:F3ANY  2 "register_operand" " v")]
> +		      UNSPEC_MAXNM_F3))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fmaxnm.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "fmin<mode>3"
> +  [(set (match_operand:F3ANY		 0 "register_operand" "=v")
> +	(unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
> +		       (match_operand:F3ANY  2 "register_operand" " v")]
> +		      UNSPEC_MINNM_F3))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fminnm.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float compare instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_<zero_inst>_<mode>3"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(FCMPZ:CC (match_operand:F3ANY 0 "register_operand" "v")
> +		  (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +   "fcmp<zero_inst>.<f3t>\t%0"
> +)
> +
> +(define_insn "*fpv3_<reg_inst>_<mode>3"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(FCMP:CC (match_operand:F3ANY 0 "register_operand" "v")
> +		 (match_operand:F3ANY 1 "register_operand" "v")))]
> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +   "fcmp<reg_inst>.<f3t>\t%0, %1"
> +)
> +
> +(define_insn "*fpv3_gt<mode>3"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(gt:CC (match_operand:F3ANY 0 "register_operand" "v")
> +	       (match_operand:F3ANY 1 "register_operand" "v")))]
> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +   "fcmplt.<f3t>\t%1, %0"
> +)
> +
> +(define_insn "*fpv3_le<mode>3"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(le:CC (match_operand:F3ANY 0 "register_operand" "v")
> +	       (match_operand:F3ANY 1 "register_operand" "v")))]
> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +   "fcmphs.<f3t>\t%1, %0"
> +)
> +
> +(define_insn "*fpv3_unordered"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
> +		      (match_operand:F3ANY 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fcmpuo.<f3t>\t%0, %1")
> +
> +(define_insn "*fpv3_unordered_zero"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
> +		      (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fcmpuoz.<f3t>\t%0")
> +
> +;; -------------------------------------------------------------------------
> +;; Float ADD instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_add<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(plus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +		    (match_operand:F3ANY  2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fadd.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float SUB instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_sub<mode>3"
> +  [(set (match_operand:F3ANY	       0 "register_operand" "=v")
> +	(minus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +		     (match_operand:F3ANY  2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fsub.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float NEG instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_neg<mode>2"
> +  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
> +	(neg:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fneg.<f3t>\t%0, %1"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float ABS instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_abs<mode>2"
> +  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
> +	(abs:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fabs.<f3t>\t%0, %1"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float common convert instructions
> +;; -------------------------------------------------------------------------
> +
> +;; SF <- HF
> +(define_insn "*fpv3_extendhfsf2"
> +  [(set (match_operand:SF		  0 "register_operand" "=v")
> +	(float_extend:SF (match_operand:HF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "fhtos\t%0, %1")
> +
> +;; HF <- SF
> +(define_insn "*fpv3_truncsfhf2"
> +  [(set (match_operand:HF		     0 "register_operand" "=v")
> +	(float_truncate:HF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "fstoh\t%0, %1")
> +
> +;; DF <- SF
> +(define_insn "*fpv3_extendsfdf2"
> +  [(set (match_operand:DF		  0 "register_operand" "=v")
> +	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_df)"
> +  "fstod\t%0, %1")
> +
> +;; SF <- DF
> +(define_insn "*fpv3_truncdfsf2"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_df)"
> +  "fdtos\t%0, %1")
> +
> +;; DF,SF,HF <- unsigned SI,SI
> +(define_insn "*fpv3_float<floatsuop>si<mode>2"
> +  [(set (match_operand:F3ANY	   0 "register_operand" "=v")
> +	(FLOAT_SU:F3ANY (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fitof.<floatsu>32.f<f3t>\t%0, %1")
> +
> +;; HF <- unsigned HI,HI
> +(define_insn "*fpv3_float<floatsuop>hihf2"
> +  [(set (match_operand:HF	   0 "register_operand" "=v")
> +	(FLOAT_SU:HF (match_operand:HI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
> +  "fitof.<floatsu>16.f16\t%0, %1")
> +
> +;; unsigned SI,SI <- DF,SF,HF
> +(define_insn "*fpv3_fix<fixsuop>_trunc<mode>si2"
> +  [(set (match_operand:SI	    0 "register_operand" "=v")
> +	(FIX_SU:SI (fix:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fftoi.f<f3t>.<fixsu>32.rz\t%0, %1")
> +
> +;; -------------------------------------------------------------------------
> +;; Float complex convert instructions
> +;; -------------------------------------------------------------------------
> +
> +;; Fixed point to floating point conversions.
> +
> +;(define_insn "*combine_fcvt_fixed16_<mode>"
> +;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
> +;	(mult:F3ANY (float:F3ANY (match_operand:HI 1 "register_operand" "0"))
> +;	       (match_operand 2
> +;			"const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
> +;   && CSKY_ISA_FEATURE(fpv3_hi)"
> +;  "fxtof.s16.f<f3t>\t%0, %1, %v2")
> +;
> +;(define_insn "*combine_fcvt_fixed32_<mode>"
> +;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
> +;	(mult:F3ANY (float:F3ANY (match_operand:SI 1 "register_operand" "0"))
> +;	       (match_operand 2
> +;			"const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
> +;  "fxtof.s32.f<f3t>\t%0, %1, %v2")
> +;
> +;(define_insn "*combine_fcvt_unfixed16_<mode>"
> +;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
> +;	(mult:F3ANY (unsigned_float:F3ANY (match_operand:HI 1 "register_operand" "0"))
> +;	       (match_operand 2
> +;			"const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
> +;   && CSKY_ISA_FEATURE(fpv3_hi)"
> +;  "fxtof.u16.f<f3t>\t%0, %1, %v2")
> +;
> +;(define_insn "*combine_fcvt_unfixed32_<mode>"
> +;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
> +;	(mult:F3ANY (unsigned_float:F3ANY (match_operand:SI 1 "register_operand" "0"))
> +;	       (match_operand 2
> +;			"const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
> +;  "fxtof.u32.f<f3t>\t%0, %1, %v2")
> +
> +;; Floating point to fixed point conversions.
> +
> +;(define_insn "*combine_fcvt<mode>_fixed16"
> +;  [(set (match_operand:HI 0 "register_operand" "=v")
> +;	(fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
> +;			    (match_operand 2
> +;			     "const_double_fcvt_power_of_two_hq" "Du")))))]
> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
> +;   && CSKY_ISA_FEATURE(fpv3_hi)"
> +;  "fftox.f<f3t>.s16\t%0, %1, %v2"
> +; )
> +;
> +;(define_insn "*combine_fcvt<mode>_fixed32"
> +;  [(set (match_operand:SI 0 "register_operand" "=v")
> +;	(fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
> +;			    (match_operand 2
> +;			     "const_double_fcvt_power_of_two_sq" "Du")))))]
> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
> +;  "fftox.f<f3t>.s32\t%0, %1, %v2"
> +; )
> +;
> +;(define_insn "*combine_fcvt<mode>_unfixed16"
> +;  [(set (match_operand:HI 0 "register_operand" "=v")
> +;	(unsigned_fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
> +;				     (match_operand 2
> +;				      "const_double_fcvt_power_of_two_hq" "Du")))))]
> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
> +;   && CSKY_ISA_FEATURE(fpv3_hi)"
> +;  "fftox.f<f3t>.u16\t%0, %1, %v2"
> +; )
> +;
> +;(define_insn "*combine_fcvt<mode>_unfixed32"
> +;  [(set (match_operand:SI 0 "register_operand" "=v")
> +;	(unsigned_fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
> +;				     (match_operand 2
> +;				      "const_double_fcvt_power_of_two_sq" "Du")))))]
> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
> +;  "fftox.f<f3t>.u32\t%0, %1, %v2"
> +; )
> +
> +;; conversions need to be rounding to nearest.
> +
> +(define_insn "l<frm_pattern><fixsuop><mode>si2"
> +  [(set (match_operand:SI 0 "register_operand" "=v")
> +	(FIX_SU:SI (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")]
> +				   FRM)))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fftoi.f<f3t>.<fixsu>32<rm>\t%0, %1"
> +)
> +
> +(define_insn "<frm_pattern><mode>2"
> +  [(set (match_operand:F3ANY 0 "register_operand" "=v")
> +	(unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")] FRMF))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fftofi.f<f3t><rm>\t%0, %1"
> +)
> +
> +;; Write Floating-point Control Register.
> +(define_insn "csky_setfcrsi"
> +  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FCR)]
> +  "CSKY_ISA_FEATURE(fcr)"
> +  "mtcr\t%0, fcr"
> +)
> +
> +;; Read Floating-point Control Register.
> +(define_insn "csky_getfcrsi"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +	(unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FCR))]
> +  "CSKY_ISA_FEATURE(fcr)"
> +  "mfcr\t%0, fcr"
> +)
> +
> +;; Insert Floating-point Control Register.
> +(define_insn "csky_insfcrsi"
> +  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
> +		     (match_operand:SI 1 "const_int_operand" "i")
> +		     (match_operand:SI 2 "const_int_operand" "i")]VUNSPEC_INS_FCR)
> +   (clobber (reg: SI 13))]
> +  "CSKY_ISA_FEATURE(fcr)"
> +  {
> +    operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1);
> +    return "mfcr\tt1, fcr\n\tins\tt1, %0, %1, %2\n\tmtcr\tt1, fcr";
> +  }
> +)
> diff --git a/gcc/config/csky/csky_isa.def b/gcc/config/csky/csky_isa.def
> index 5edce16..5849819 100644
> --- a/gcc/config/csky/csky_isa.def
> +++ b/gcc/config/csky/csky_isa.def
> @@ -32,6 +32,7 @@ CSKY_ISA (7E10,	 "Extended insns for arch ck810	 from ck807")
>   
>   /* Special insns */
>   CSKY_ISA (div,	  "divide insns")
> +CSKY_ISA (fcr,	  "Control the fcr register")
>   
>   /* Extended insns */
>   CSKY_ISA (dsp,	 "Extended insns for DSP")
> @@ -41,6 +42,11 @@ CSKY_ISA (fpv2_sf,    "Single precision operations supported")
>   CSKY_ISA (fpv2_df,    "Double precision operations supported")
>   CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
>   
> +CSKY_ISA (fpv3_hi,    "half word for fpu convert supported")
> +CSKY_ISA (fpv3_hf,    "half precision operations supported")
> +CSKY_ISA (fpv3_sf,    "Single precision operations supported")
> +CSKY_ISA (fpv3_df,    "Double precision operations supported")
> +
>   /* Specific insns mode */
>   #ifdef	CSKY_ISA_MACRO
>   #define CSKY_ISA_CK801	    CSKY_ISA_FEATURE_GET (E1)
> @@ -50,10 +56,19 @@ CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
>   #define CSKY_ISA_CK803R1    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E3r1)
>   #define CSKY_ISA_CK807	    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E7)
>   #define CSKY_ISA_CK810	    CSKY_ISA_CK807, CSKY_ISA_FEATURE_GET (7E10)
> +#define CSKY_ISA_CK860      CSKY_ISA_CK810, CSKY_ISA_FEATURE_GET(3E3r1)
>   
>   #define CSKY_ISA_DSP	    CSKY_ISA_FEATURE_GET (dsp)
>   
>   #define CSKY_ISA_FPv2_SF    CSKY_ISA_FEATURE_GET (fpv2_sf)
>   #define CSKY_ISA_FPv2	    CSKY_ISA_FPv2_SF, CSKY_ISA_FEATURE_GET (fpv2_df)
>   #define CSKY_ISA_FPv2_DIVD  CSKY_ISA_FPv2, CSKY_ISA_FEATURE_GET (fpv2_divd)
> +
> +#define CSKY_ISA_FPv3_HF    CSKY_ISA_FEATURE_GET (fpv3_hf), \
> +                            CSKY_ISA_FEATURE_GET (fpv3_hi)
> +#define CSKY_ISA_FPv3_HSF   CSKY_ISA_FPv3_HF, \
> +                            CSKY_ISA_FEATURE_GET (fpv3_sf)
> +#define CSKY_ISA_FPv3_SDF   CSKY_ISA_FEATURE_GET (fpv3_sf), \
> +                            CSKY_ISA_FEATURE_GET (fpv3_df)
> +#define CSKY_ISA_FPv3       CSKY_ISA_FPv3_HF, CSKY_ISA_FPv3_SDF
>   #endif
> diff --git a/gcc/config/csky/csky_tables.opt b/gcc/config/csky/csky_tables.opt
> index 3501f90..ca113dd 100644
> --- a/gcc/config/csky/csky_tables.opt
> +++ b/gcc/config/csky/csky_tables.opt
> @@ -194,6 +194,12 @@ Enum(csky_processor_type) String(ck810ft) Value( TARGET_CPU_ck810ff)
>   EnumValue
>   Enum(csky_processor_type) String(ck810ftv) Value( TARGET_CPU_ck810ftv)
>   
> +EnumValue
> +Enum(csky_processor_type) String(ck860) Value( TARGET_CPU_ck860)
> +
> +EnumValue
> +Enum(csky_processor_type) String(ck860f) Value( TARGET_CPU_ck860f)
> +
>   Enum
>   Name(csky_arch) Type(int)
>   Known CSKY architectures (for use with the -march= option):
> @@ -213,6 +219,9 @@ Enum(csky_arch) String(ck807) Value(3)
>   EnumValue
>   Enum(csky_arch) String(ck810) Value(4)
>   
> +EnumValue
> +Enum(csky_arch) String(ck860) Value(5)
> +
>   Enum
>   Name(csky_fpu) Type(enum csky_fpu_type)
>   Known CSKY FPUs (for use with the -mfpu= option):
> @@ -227,4 +236,16 @@ EnumValue
>   Enum(csky_fpu) String(fpv2_divd) Value(TARGET_FPU_fpv2_divd)
>   
>   EnumValue
> +Enum(csky_fpu) String(fpv3_hf) Value(TARGET_FPU_fpv3_hf)
> +
> +EnumValue
> +Enum(csky_fpu) String(fpv3_hsf) Value(TARGET_FPU_fpv3_hsf)
> +
> +EnumValue
> +Enum(csky_fpu) String(fpv3_sdf) Value(TARGET_FPU_fpv3_sdf)
> +
> +EnumValue
> +Enum(csky_fpu) String(fpv3) Value(TARGET_FPU_fpv3)
> +
> +EnumValue
>   Enum(csky_fpu) String(auto) Value(TARGET_FPU_auto)
> diff --git a/gcc/config/csky/predicates.md b/gcc/config/csky/predicates.md
> index 4ffecb0..878446d 100644
> --- a/gcc/config/csky/predicates.md
> +++ b/gcc/config/csky/predicates.md
> @@ -294,5 +294,4 @@
>   })
>   
>   (define_special_predicate "csky_float_comparison_operator"
> -  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
> -	       unordered,ordered"))
> +  (match_code "eq,ne,le,lt,ge,gt,unordered,ordered"))
> diff --git a/gcc/config/csky/t-csky-elf b/gcc/config/csky/t-csky-elf
> index bbdf286..4e7fcbe 100644
> --- a/gcc/config/csky/t-csky-elf
> +++ b/gcc/config/csky/t-csky-elf
> @@ -27,8 +27,8 @@ MULTILIB_MATCHES      = mbig-endian=EB
>   MULTILIB_EXCEPTIONS   =
>   
>   # Arch variants.
> -MULTILIB_OPTIONS     += mcpu=ck802/mcpu=ck801/mcpu=ck803f/mcpu=ck807f/mcpu=ck810f
> -MULTILIB_DIRNAMES    += ck802 ck801 ck803 ck807 ck810
> +MULTILIB_OPTIONS     += mcpu=ck802/mcpu=ck801/mcpu=ck803f/mcpu=ck807f/mcpu=ck810f/mcpu=ck860f
> +MULTILIB_DIRNAMES    += ck802 ck801 ck803 ck807 ck810 ck860
>   
>   # For arch ck802.
>   MULTILIB_MATCHES     += mcpu?ck802=march?ck802
> @@ -100,6 +100,11 @@ MULTILIB_MATCHES     += mcpu?ck807f=march?ck807ef
>   MULTILIB_MATCHES     += mcpu?ck807f=march?ck807
>   MULTILIB_MATCHES     += mcpu?ck807f=mcpu?ck807
>   
> +# For arch ck860
> +MULTILIB_MATCHES     += mcpu?ck860f=march?ck860
> +MULTILIB_MATCHES     += mcpu?ck860f=mcpu?ck860
> +MULTILIB_MATCHES     += mcpu?ck860f=mcpu?c860
> +
>   # For option -mfloat-abi=
>   MULTILIB_OPTIONS     += mfloat-abi=soft/mfloat-abi=softfp/mfloat-abi=hard
>   MULTILIB_DIRNAMES    += soft soft-fp hard-fp
> diff --git a/gcc/config/csky/t-csky-linux b/gcc/config/csky/t-csky-linux
> index 9435b7a..0730c3a 100644
> --- a/gcc/config/csky/t-csky-linux
> +++ b/gcc/config/csky/t-csky-linux
> @@ -21,11 +21,11 @@
>   
>   
>   MULTILIB_EXCEPTIONS  =
> -CSKY_MULTILIB_OSDIRNAMES = mfloat-abi.softfp=/soft-fp mfloat-abi.hard=/hard-fp mfloat-abi.soft=/. mcpu.ck810f=/. mcpu.ck807f=/ck807
> +CSKY_MULTILIB_OSDIRNAMES = mfloat-abi.softfp=/soft-fp mfloat-abi.hard=/hard-fp mfloat-abi.soft=/. mcpu.ck810f=/. mcpu.ck807f=/ck807 mcpu.ck860f=/ck860
>   
>   # Arch variants.
> -MULTILIB_OPTIONS     += mcpu=ck810f/mcpu=ck807f
> -MULTILIB_DIRNAMES    += ck810 ck807
> +MULTILIB_OPTIONS     += mcpu=ck810f/mcpu=ck807f/mcpu=ck860f
> +MULTILIB_DIRNAMES    += ck810 ck807 ck860
>   
>   # For ck807.
>   MULTILIB_MATCHES     += mcpu?ck807f=march?ck807
> @@ -41,6 +41,11 @@ MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810vf
>   MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810ft
>   MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810vft
>   
> +# For ck860
> +MULTILIB_MATCHES     += mcpu?ck860f=march?ck860
> +MULTILIB_MATCHES     += mcpu?ck860f=mcpu?ck860
> +MULTILIB_MATCHES     += mcpu?ck860f=mcpu?c860
> +
>   # For option -mfloat-abi=
>   MULTILIB_OPTIONS     += mfloat-abi=soft/mfloat-abi=softfp/mfloat-abi=hard
>   MULTILIB_DIRNAMES    += soft soft-fp hard-fp
> diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
> index d166a0d..11b5868 100644
> --- a/gcc/doc/md.texi
> +++ b/gcc/doc/md.texi
> @@ -2258,6 +2258,14 @@ Vector registers.
>   
>   @item z
>   Stack pointer register (SP).
> +
> +@item Q
> +A memory address which uses a base register with a short offset
> +or with a index register with its scale.
> +
> +@item W
> +A memory address which uses a base register with a index register
> +with its scale.
>   @end table
>   
>   @ifset INTERNALS

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] C-SKY: Add fpuv3 instructions and CK860 arch.
  2021-05-24 10:49 ` Xianmiao Qu
@ 2021-05-24 11:32   ` Xianmiao Qu
  0 siblings, 0 replies; 5+ messages in thread
From: Xianmiao Qu @ 2021-05-24 11:32 UTC (permalink / raw)
  To: Geng Qi, gcc-patches

BTW, I modified some of the inappropriate descriptions in the changelog

gcc/ChangeLog:

     * config/csky/constraints.md ("W"): New constriant for mem operand
     with base reg, index register.
     ("Q"): Renamed and modified "csky_valid_fpuv2_mem_operand" to
     "csky_valid_mem_constraint_operand" to deal with both "Q" and "W"
     constraint.
     ("Dv"): New constraint for const double value that can be used at
     fmovi instruction.
     * config/csky/csky-modes.def (HFmode): New mode.
     * config/csky/csky-protos.h (csky_valid_fpuv2_mem_operand): Rename
     to "csky_valid_mem_constraint_operand" and support new constraint
     "W".
     (csky_get_movedouble_length): New.
     (fpuv3_output_move): New.
     (fpuv3_const_double): New.
     * config/csky/csky.c (csky_option_override): New arch CK860 with fpv3.
     (decompose_csky_address): Refine.
     (csky_print_operand): New "CONST_DOUBLE" operand.
     (csky_output_move): Support fpv3 instructions.
     (csky_get_movedouble_length): New.
     (fpuv3_output_move): New.
     (fpuv3_const_double): New.
     (csky_emit_compare): Cover float comparsion.
     (csky_emit_compare_float): Refine.
     (csky_vaild_fpuv2_mem_operand): Rename to
     "csky_valid_mem_constraint_operand" and support new constraint "W".
     (ck860_rtx_costs): New.
     (csky_rtx_costs): Add the cost calculation of CK860.
     (regno_reg_class): New vregs for fpuv3.
     (csky_dbx_regno): Likewise.
     (csky_cpu_cpp_builtins): New builtin macro for fpuv3.
     (csky_conditional_register_usage): Support fpuv3.
     (csky_dwarf_register_span): Support fpuv3.
     (csky_init_builtins, csky_mangle_type): Support "__fp16" type.
     (ck810_legitimate_index_p): Support fp16.
     * gcc/config/csky/csky.h (TARGET_TLS): Add CK860.
     (CSKY_VREG_P, CSKY_VREG_LO_P, CSKY_VREG_HI_P): Support fpuv3.
     (TARGET_SINGLE_FPU): Support fpuv3.
     (TARGET_SUPPORT_FPV3): New.
     (FIRST_PSEUDO_REGISTER): Change to 202 to hold the new fpuv3 registers.
     (FIXED_REGISTERS, CALL_REALLY_USED_REGISTERS, REGISTER_NAMES,
      REG_CLASS_CONTENTS): Support fpuv3.
     * gcc/config/csky/csky.md (movsf): Move to csky_insn_fpu.md and refine.
     (csky_movsf_fpv2): Likewise.
     (ck801_movsf): Likewise.
     (csky_movsf): Likewise.
     (movdf): Likewise.
     (csky_movdf_fpv2): Likewise.
     (ck801_movdf): Likewise.
     (csky_movdf): Likewise.
     (movsicc): Refine. Use "comparison_operatior" instead of
     "ordered_comparison_operatior".
     (addsicc): Likewise.
     (CSKY_FIRST_VFP3_REGNUM, CSKY_LAST_VFP3_REGNUM): New constant.
     (*call_value_internal_vh): New.
     * config/csky/csky_cores.def (CK860): New arch and cpu.
     (fpv3_hf): New.
     (fpv3_hsf): New.
     (fpv3_sdf): New.
     (fpv3): New.
     * config/csky/csky_insn_fpu.md : Refactor. Separate all float patterns
     into emit-patterns and match-patterns, remain the emit-patterns here,
     and move the match-patterns to csky_insn_fpuv2.md or 
csky_insn_fpuv3.md.
     * config/csky/csky_insn_fpuv2.md: New file for fpuv2 instructions.
     * config/csky/csky_insn_fpuv3.md: New flie and new patterns for fpuv3
     isntructions.
     * config/csky/csky_isa.def (fcr): New.
     (fpv3_hi): New.
     (fpv3_hf): New.
     (fpv3_sf): New.
     (fpv3_df): New.
     (CK860): New definition for ck860.
     * gcc/config/csky/csky_tables.opt (ck860): New processors ck860,
     ck860f. And new arch ck860.
     (fpv3_hf): New.
     (fpv3_hsf): New.
     (fpv3_sdf): New.
     (fpv3): New.
     * config/csky/predicates.md (csky_float_comparsion_operator): Delete
     "geu", "gtu", "leu", "ltu", which will never appear at float 
comparison.
     * config/csky/t-csky-elf, config/csky/t-csky-linux: Support 860.
     * doc/md.texi: Add "Q" and "W" constraints for C-SKY.


On 5/24/21 6:49 PM, Xianmiao Qu wrote:
> Hi Geng Qi,
>
>
> I tested this patch but it got the following error when compiling libgcc,
>
> during RTL pass: 
> reload/lhome/quxm/build-csky-upstream/source//gcc/libgcc/libgcc2.c: In 
> function 
> '__mulsc3':/lhome/quxm/build-csky-upstream/source//gcc/libgcc/libgcc2.c:2010:1: 
> internal compiler error: maximum number of generated reload insns per 
> insn achieved 
> (90)/lhome/quxm/build-csky-upstream/source//gcc/libgcc/libgcc2.c: In 
> function 
> '__divsc3':/lhome/quxm/build-csky-upstream/source//gcc/libgcc/libgcc2.c:2175:1: 
> internal compiler error: maximum number of generated reload insns per 
> insn achieved (90)
>
> Is it related to the patches you send later? If so, please use [PATCH 
> n/m] format to merge them together.
>
>
> Thanks,
>
> Xianmiao
>
>
> On 4/30/21 8:21 PM, Geng Qi wrote:
>> gcc/ChangeLog:
>>
>>     * config/csky/constraints.md ("W"): New constriant for mem operand
>>     with base reg, index register.
>>     ("Q"): Renamed and modified "csky_valid_fpuv2_mem_operand" to
>>     "csky_valid_mem_constraint_operand" to deal with both "Q" and "W"
>>     constraint.
>>     ("Dv"): New constraint for const double value that can be used at
>>     fmovi instruction.
>>     * config/csky/csky-modes.def (HFmode): New mode.
>>     * config/csky/csky-protos.h (csky_valid_fpuv2_mem_operand): Rename
>>     to "csky_valid_mem_constraint_operand" and new support for 
>> constraint
>>     "W".
>>     (csky_get_movedouble_length): New.
>>     (fpuv3_output_move): New.
>>     (fpuv3_const_double): New.
>>     * config/csky/csky.c (csky_option_override): New arch CK860 with 
>> fpv3.
>>     (decompose_csky_address): Robustness adjust.
>>     (csky_print_operand): New "CONST_DOUBLE" operand.
>>     (csky_output_move): New support for fpv3 instructions.
>>     (csky_get_movedouble_length): New.
>>     (fpuv3_output_move): New.
>>     (fpuv3_const_double): New.
>>     (csky_emit_compare): New cover for float comparsion.
>>     (csky_emit_compare_float): Refine.
>>     (csky_vaild_fpuv2_mem_operand): Rename to
>>     "csky_valid_mem_constraint_operand" and new support for 
>> constraint "W".
>>     (ck860_rtx_costs): New.
>>     (csky_rtx_costs): New subcall for CK860.
>>     (regno_reg_class): New vregs for fpuv3.
>>     (csky_dbx_regno): Likewise.
>>     (csky_cpu_cpp_builtins): New builtin macro for fpuv3.
>>     (csky_conditional_register_usage): New suporrot for fpuv3.
>>     (csky_dwarf_register_span): New suporrot for fpuv3.
>>     (csky_init_builtins, csky_mangle_type): New support for "__fp16" 
>> type.
>>     (ck810_legitimate_index_p): New support for fp16.
>>     * gcc/config/csky/csky.h (TARGET_TLS): ADD CK860.
>>     (CSKY_VREG_P, CSKY_VREG_LO_P, CSKY_VREG_HI_P): New support for 
>> fpuv3.
>>     (TARGET_SINGLE_FPU): New support for fpuv3.
>>     (TARGET_SUPPORT_FPV3): New macro.
>>     (FIRST_PSEUDO_REGISTER): Value change, since the new fpuv3 regs.
>>     (FIXED_REGISTERS, CALL_REALLY_USED_REGISTERS, REGISTER_NAMES,
>>      REG_CLASS_CONTENTS): Support for fpuv3.
>>     * gcc/config/csky/csky.md (movsf): Move to cksy_insn_fpu.md and 
>> adjust.
>>     (csky_movsf_fpv2): Likewise.
>>     (ck801_movsf): Likewise.
>>     (csky_movsf): Likewise.
>>     (movdf): Likewise.
>>     (csky_movdf_fpv2): Likewise.
>>     (ck801_movdf): Likewise.
>>     (csky_movdf): Likewise.
>>     (movsicc): Refine. Use "comparison_operatior" instead of
>>     "ordered_comparison_operatior".
>>     (addsicc): Likewise.
>>     (CSKY_FIRST_VFP3_REGNUM, CSKY_LAST_VFP3_REGNUM): New constant.
>>     (call_value_internal_vh): New insn.
>>     * config/csky/csky_cores.def (CK860): New arch and cpu.
>>     (fpv3): New 4 fpus: fpv3_hf, fpv3_hsf, fpv3_sdf and fpv3.
>>     * config/csky/csky_insn_fpu.md (mov<float_mode>): Move the float mov
>>     patterns from csky.md here.
>>     (fpuv2 instructions): Refactor. Separate all float patterns into
>>     emit-patterns and match-patterns, remain the emit-patterns here, and
>>     move the match-patterns to csky_insn_fpuv2.md.
>>     (fpuv3 instructions): Add patterns and fuse part of them with the
>>     fpuv2's.
>>     * config/csky/csky_insn_fpuv2.md: New file for fpuv2 instructions.
>>     * config/csky/csky_insn_fpuv3.md: New flie and new patterns for 
>> fpuv3
>>     isntructions.
>>     * config/csky/csky_isa.def (fcr): New.
>>     (fpv3): New 4 isa sets: fpv3_hi, fpv3_hf, fpv3_sf and fpv3_df.
>>     (CK860): New definition for ck860.
>>     * gcc/config/csky/csky_tables.opt (ck860): New processors ck860,
>>     ck860f. And new arch ck860.
>>     (fpv3): New 4 fpus: fpv3_hf, fpv3_hsf, fpv3_sdf and fpv3.
>>     * config/csky/predicates.md (csky_float_comparsion_operator): Delete
>>     "geu", "gtu", "leu", "ltu", which will never appear at float 
>> comparison.
>>     * config/cksy/t-csky-elf, config/csky/t-csky-linux: New for ck860.
>>     * doc/md.texi: Add "Q" and "W" constraints for C-SKY.
>> ---
>>   gcc/config/csky/constraints.md     |  13 +-
>>   gcc/config/csky/csky-modes.def     |   2 +
>>   gcc/config/csky/csky-protos.h      |   7 +-
>>   gcc/config/csky/csky.c             | 644 
>> ++++++++++++++++++++++++++----
>>   gcc/config/csky/csky.h             | 162 ++++++--
>>   gcc/config/csky/csky.md            | 127 ++----
>>   gcc/config/csky/csky_cores.def     |  13 +
>>   gcc/config/csky/csky_insn_fpu.md   | 798 
>> +++++++++++++++----------------------
>>   gcc/config/csky/csky_insn_fpuv2.md | 470 ++++++++++++++++++++++
>>   gcc/config/csky/csky_insn_fpuv3.md | 497 +++++++++++++++++++++++
>>   gcc/config/csky/csky_isa.def       |  15 +
>>   gcc/config/csky/csky_tables.opt    |  21 +
>>   gcc/config/csky/predicates.md      |   3 +-
>>   gcc/config/csky/t-csky-elf         |   9 +-
>>   gcc/config/csky/t-csky-linux       |  11 +-
>>   gcc/doc/md.texi                    |   8 +
>>   16 files changed, 2125 insertions(+), 675 deletions(-)
>>   create mode 100644 gcc/config/csky/csky-modes.def
>>   create mode 100644 gcc/config/csky/csky_insn_fpuv2.md
>>   create mode 100644 gcc/config/csky/csky_insn_fpuv3.md
>>
>> diff --git a/gcc/config/csky/constraints.md 
>> b/gcc/config/csky/constraints.md
>> index 6067d3d..937cb81 100644
>> --- a/gcc/config/csky/constraints.md
>> +++ b/gcc/config/csky/constraints.md
>> @@ -34,7 +34,11 @@
>>     (define_memory_constraint "Q"
>>     "Memory operands with base register, index register and short 
>> displacement for FPUV2"
>> -  (match_test "csky_valid_fpuv2_mem_operand (op)"))
>> +  (match_test "csky_valid_mem_constraint_operand (op, \"Q\")"))
>> +
>> +(define_memory_constraint "W"
>> +  "Memory operands with base register, index register"
>> +  (match_test "csky_valid_mem_constraint_operand (op, \"W\")"))
>>     (define_constraint "R"
>>     "Memory operands whose address is a label_ref"
>> @@ -172,3 +176,10 @@
>>     "Constant in range [-8, -1]"
>>     (and (match_code "const_int")
>>          (match_test "CSKY_CONST_OK_FOR_US (ival)")))
>> +
>> +(define_constraint "Dv"
>> + "@VFPv3
>> +  A const_double which can be used with a VFP fmovi
>> +  instruction."
>> +  (and (match_code "const_double")
>> +       (match_test "fpuv3_const_double_rtx (op)")))
>> diff --git a/gcc/config/csky/csky-modes.def 
>> b/gcc/config/csky/csky-modes.def
>> new file mode 100644
>> index 0000000..a2427ff
>> --- /dev/null
>> +++ b/gcc/config/csky/csky-modes.def
>> @@ -0,0 +1,2 @@
>> +/* Float modes.  */
>> +FLOAT_MODE (HF, 2, ieee_half_format);        /* Half-precision 
>> floating point */
>> diff --git a/gcc/config/csky/csky-protos.h 
>> b/gcc/config/csky/csky-protos.h
>> index 7a2e23e..7c6528b 100644
>> --- a/gcc/config/csky/csky-protos.h
>> +++ b/gcc/config/csky/csky-protos.h
>> @@ -30,7 +30,7 @@ extern void csky_cpu_cpp_builtins (cpp_reader *);
>>   extern bool csky_inlinable_constant (HOST_WIDE_INT value);
>>   extern bool csky_shifted_imm8_constant (unsigned HOST_WIDE_INT,
>>                       unsigned int *, unsigned int *);
>> -extern bool csky_valid_fpuv2_mem_operand (rtx);
>> +extern bool csky_valid_mem_constraint_operand (rtx, const char*);
>>     extern bool csky_minipool_load_p (rtx_insn *);
>>   extern const char *csky_output_move (rtx insn, rtx *, machine_mode);
>> @@ -70,4 +70,9 @@ extern int csky_default_branch_cost (bool, bool);
>>   extern bool csky_default_logical_op_non_short_circuit (void);
>>     extern void csky_init_cumulative_args (CUMULATIVE_ARGS *, tree, 
>> rtx, tree);
>> +extern int csky_get_movedouble_length(rtx operands[]);
>> +
>> +/* The functions was used for fpuv3.  */
>> +extern const char *fpuv3_output_move (rtx *operands);
>> +extern int fpuv3_const_double_rtx (rtx);
>>   #endif /* GCC_CSKY_PROTOS_H */
>> diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
>> index cdb95fe..6e97994 100644
>> --- a/gcc/config/csky/csky.c
>> +++ b/gcc/config/csky/csky.c
>> @@ -126,7 +126,46 @@ enum reg_class 
>> regno_reg_class[FIRST_PSEUDO_REGISTER] =
>>     /* Reserved.  */
>>     RESERVE_REGS, RESERVE_REGS,
>>     /* Register epc.  */
>> -  OTHER_REGS
>> +  OTHER_REGS,
>> +  /* Vec registers.  */
>> +  V_REGS,       V_REGS,       V_REGS,       V_REGS,
>> +  V_REGS,       V_REGS,       V_REGS,       V_REGS,
>> +  V_REGS,       V_REGS,       V_REGS,       V_REGS,
>> +  V_REGS,       V_REGS,       V_REGS,       V_REGS,
>> +  /* Reserved.  */
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  /* Reserved.  */
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
>> +
>> +  RESERVE_REGS, RESERVE_REGS, RESERVE_REGS
>>   };
>>     /* Arrays that map GCC register numbers to debugger register 
>> numbers,
>> @@ -138,11 +177,34 @@ const int csky_dbx_regno[FIRST_PSEUDO_REGISTER] =
>>     8,  9,  10, 11, 12, 13, 14, 15,
>>     16, 17, 18, 19, 20, 21, 22, 23,
>>     24, 25, 26, 27, 28, 29, 30, 31,
>> -  -1, -1, 36, 37, -1, -1, -1, -1,
>> -  -1, -1, -1, -1, -1, -1, -1, -1,
>> -  -1, -1, -1, -1, 56, 57, 58, 59,
>> -  60, 61, 62, 63, 64, 65, 66, 67,
>> -  68, 69, 70, 71, -1, -1, 72
>> +  -1, -1, 36, 37,
>> +  75,  79,  83,  87,  91,  95,  99,  103,
>> +  107, 111, 115, 119, 123, 127, 131, 135,
>> +  74,  78,  82,  86,  90,  94,  98,  102,
>> +  106, 110, 114, 118, 122, 126, 130, 134,
>> +  -1, -1, 72,
>> +  /* vr: 71 - 86 */
>> +  139,  143,  147,  151,  155,  159,  163,  167,
>> +  171,  175,  179,  183,  187,  191,  195,  199,
>> +  138,  142,  146,  150,  154,  158,  162,  166,
>> +  170,  174,  178,  182,  186,  190,  194,  198,
>> +  /* resereved */
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +  -1,   -1,   -1,   -1,   -1,   -1,   -1,  -1,
>> +
>> +  -1,   -1,   -1
>>   };
>>     /* Table of machine attributes.  */
>> @@ -351,6 +413,12 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
>>         builtin_define ("__CSKY_FPUV2__");
>>       }
>>   +  if (TARGET_SUPPORT_FPV3)
>> +    {
>> +      builtin_define ("__csky_fpuv3__");
>> +      builtin_define ("__CSKY_FPUV3__");
>> +    }
>> +
>>     if (TARGET_ELRW)
>>       {
>>         builtin_define ("__csky_elrw__");
>> @@ -408,7 +476,6 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
>>    *               Storage Layout              *
>> ******************************************************************/
>>   -
>>   #undef    TARGET_PROMOTE_FUNCTION_MODE
>>   #define TARGET_PROMOTE_FUNCTION_MODE \
>>     default_promote_function_mode_always_promote
>> @@ -416,6 +483,9 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
>>   #undef TARGET_CONSTANT_ALIGNMENT
>>   #define TARGET_CONSTANT_ALIGNMENT csky_constant_alignment
>>   +#undef TARGET_MANGLE_TYPE
>> +#define TARGET_MANGLE_TYPE csky_mangle_type
>> +
>> /******************************************************************
>>    *        Stack Layout and Calling Conventions          *
>> @@ -692,6 +762,15 @@ csky_default_logical_op_non_short_circuit (void)
>>   #define     TARGET_SCHED_ADJUST_COST csky_sched_adjust_cost
>> +/******************************************************************
>> + *            Builtin                      *
>> + ******************************************************************/
>> +
>> +
>> +#undef  TARGET_INIT_BUILTINS
>> +#define TARGET_INIT_BUILTINS  csky_init_builtins
>> +
>> +
>>   /* The declaration of functions.  */
>>   static void push_csky_minipool_fix (rtx_insn *, HOST_WIDE_INT, rtx *,
>>                       machine_mode, rtx);
>> @@ -837,6 +916,7 @@ Mfix *minipool_fix_tail;
>>   Mfix *minipool_barrier;
>>     /* Allow GC scanning of the minipool obstack.  */
>> +
>>   static void
>>   csky_add_gc_roots (void)
>>   {
>> @@ -846,6 +926,7 @@ csky_add_gc_roots (void)
>>     /* Implement TARGET_CONSTANT_ALIGNMENT.
>>      Make strings word-aligned so strcpy from constants will be 
>> faster.  */
>> +
>>   static HOST_WIDE_INT
>>   csky_constant_alignment (const_tree exp, HOST_WIDE_INT align)
>>   {
>> @@ -1109,6 +1190,7 @@ get_csky_barrier_cost (rtx_insn *insn)
>>      (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
>>      Create the barrier by inserting a jump and add a new fix entry for
>>      it.  */
>> +
>>   static Mfix *
>>   create_csky_fix_barrier (Mfix *fix, Mfix *fix_next,
>>                HOST_WIDE_INT max_address)
>> @@ -1455,6 +1537,7 @@ csky_compute_pushpop_length (rtx *operands)
>>   }
>>     /* Emit constant pools for -mconstpool.  */
>> +
>>   static void
>>   csky_emit_constant_pools (void)
>>   {
>> @@ -1796,6 +1879,7 @@ csky_initial_elimination_offset (int from, int to)
>>      CUM is a variable of type CUMULATIVE_ARGS which gives info about
>>       the preceding args and about the function being called.
>>      ARG is a description of the argument.  */
>> +
>>   static rtx
>>   csky_function_arg (cumulative_args_t pcum_v, const 
>> function_arg_info &arg)
>>   {
>> @@ -1921,6 +2005,7 @@ csky_function_value (const_tree type, 
>> const_tree func,
>>       /* Implement TARGET_LIBCALL_VALUE.  */
>> +
>>   static rtx
>>   csky_libcall_value (machine_mode mode,
>>               const_rtx libcall ATTRIBUTE_UNUSED)
>> @@ -1949,6 +2034,7 @@ csky_function_value_regno_p (const unsigned int 
>> regno)
>>     /* Return an RTX indicating where the return address to the
>>      calling function can be found.  */
>> +
>>   rtx
>>   csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
>>   {
>> @@ -1964,6 +2050,7 @@ csky_return_addr (int count, rtx frame 
>> ATTRIBUTE_UNUSED)
>>      that must be put in registers. The value must be zero for arguments
>>      that are passed entirely in registers or
>>      that are entirely pushed on the stack.  */
>> +
>>   static int
>>   csky_arg_partial_bytes (cumulative_args_t pcum_v, const 
>> function_arg_info &arg)
>>   {
>> @@ -2180,7 +2267,19 @@ csky_conditional_register_usage (void)
>>         int regno;
>>           for (regno = CSKY_FIRST_VFP_REGNUM;
>> -       regno <= CSKY_LAST_VFP_REGNUM; regno++)
>> +       regno <= CSKY_LAST_VFP3_REGNUM; regno++)
>> +    {
>> +      fixed_regs[regno] = 1;
>> +      call_used_regs[regno] = 1;
>> +    }
>> +    }
>> +
>> +  if (!TARGET_SUPPORT_FPV3)
>> +    {
>> +      int regno;
>> +
>> +      for (regno = CSKY_FIRST_VFP3_REGNUM;
>> +       regno <= CSKY_LAST_VFP3_REGNUM; regno++)
>>       {
>>         fixed_regs[regno] = 1;
>>         call_used_regs[regno] = 1;
>> @@ -2198,6 +2297,7 @@ csky_conditional_register_usage (void)
>>   }
>>     /* Implement TARGET_HARD_REGNO_NREGS.  */
>> +
>>   static unsigned int
>>   csky_hard_regno_nregs (unsigned int regno, machine_mode mode)
>>   {
>> @@ -2261,6 +2361,7 @@ csky_hard_regno_mode_ok (unsigned int regno, 
>> machine_mode mode)
>>   /* Implement TARGET_MODES_TIEABLE_P.  We can't tie DFmode with 
>> other modes
>>      when V_REGs might be in use because those registers mess with 
>> the stored
>>      bits.  */
>> +
>>   static bool
>>   csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
>>   {
>> @@ -2272,6 +2373,7 @@ csky_modes_tieable_p (machine_mode mode1, 
>> machine_mode mode2)
>>   /* Implement TARGET_CAN_CHANGE_MODE_CLASS.
>>      V_REG registers can't do subreg as all values are reformatted to
>>      internal precision.  */
>> +
>>   static bool
>>   csky_can_change_mode_class (machine_mode from,
>>                   machine_mode to,
>> @@ -2406,6 +2508,7 @@ csky_spill_class (reg_class_t rclass, 
>> machine_mode mode ATTRIBUTE_UNUSED)
>>     /* Convert a static initializer array of feature bits to sbitmap
>>      representation.  */
>> +
>>   static void
>>   csky_initialize_isa (sbitmap isa, const enum csky_isa_feature 
>> *isa_bits)
>>   {
>> @@ -2417,6 +2520,7 @@ csky_initialize_isa (sbitmap isa, const enum 
>> csky_isa_feature *isa_bits)
>>     /* Configure a build target TARGET from the user-specified 
>> options OPTS and
>>      OPTS_SET.  */
>> +
>>   static void
>>   csky_configure_build_target (struct csky_build_target *target,
>>                    struct cl_target_option *opts,
>> @@ -2508,7 +2612,9 @@ csky_option_override (void)
>>       csky_base_arch = csky_active_target.base_arch;
>>   -  if (flag_pic && !(CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH 
>> (CK807)))
>> +  if (flag_pic && !(CSKY_TARGET_ARCH (CK807)
>> +           || CSKY_TARGET_ARCH (CK810)
>> +           || CSKY_TARGET_ARCH (CK860)))
>>       {
>>         flag_pic = 0;
>>         warning (0, "%qs is not supported by arch %s",
>> @@ -2526,19 +2632,21 @@ csky_option_override (void)
>>         bool ok;
>>         int fpu_index;
>>   -#ifdef CSKY_FPUTYPE_DEFAULT
>> -      target_fpu_name = CSKY_FPUTYPE_DEFAULT;
>> -#else
>> -      target_fpu_name = "fpv2";
>> -#endif
>> -
>>         if (csky_active_target.core_name != NULL
>>             && !strchr (csky_active_target.core_name, 'f'))
>>           target_fpu_name = "auto";
>>         else if (CSKY_TARGET_ARCH (CK803) || !TARGET_DOUBLE_FLOAT)
>>           target_fpu_name = "fpv2_sf";
>> +      else if (CSKY_TARGET_ARCH (CK860))
>> +        target_fpu_name = "fpv3";
>>         else if (TARGET_DOUBLE_FLOAT && TARGET_FDIVDU)
>>           target_fpu_name = "fpv2_divd";
>> +      else
>> +#ifdef CSKY_FPUTYPE_DEFAULT
>> +        target_fpu_name = CSKY_FPUTYPE_DEFAULT;
>> +#else
>> +        target_fpu_name = "fpv2";
>> +#endif
>>           ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, 
>> &fpu_index,
>>                         CL_TARGET);
>> @@ -3020,10 +3128,8 @@ ck810_legitimate_index_p (machine_mode mode, 
>> rtx index, int strict_p)
>>   {
>>     enum rtx_code code = GET_CODE (index);
>>   -  if (TARGET_HARD_FLOAT
>> -      && (mode == SFmode || mode == DFmode))
>> -    return (code == CONST_INT && INTVAL (index) < 1024
>> -        && INTVAL (index) >= 0
>> +  if (code == CONST_INT && TARGET_HARD_FLOAT && CSKY_VREG_MODE_P 
>> (mode))
>> +    return (INTVAL (index) < 1024 && INTVAL (index) >= 0
>>           && (INTVAL (index) & 3) == 0);
>>       if (code == CONST_INT)
>> @@ -3183,7 +3289,7 @@ static bool
>>   decompose_csky_address (rtx addr, struct csky_address *out)
>>   {
>>     rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
>> -  HOST_WIDE_INT scale = 1;
>> +  HOST_WIDE_INT scale = 0;
>>     rtx scale_rtx = NULL_RTX;
>>     int i;
>>   @@ -3231,7 +3337,10 @@ decompose_csky_address (rtx addr, struct 
>> csky_address *out)
>>             if (!base)
>>           base = op;
>>             else if (!index)
>> -        index = op;
>> +        {
>> +          index = op;
>> +          scale = 1;
>> +        }
>>             else
>>           return false;
>>             break;
>> @@ -3259,7 +3368,7 @@ decompose_csky_address (rtx addr, struct 
>> csky_address *out)
>>             scale_rtx = XEXP (op, 1);
>>             if (!CONST_INT_P (scale_rtx))
>>           return false;
>> -          scale = scale << INTVAL (scale_rtx);
>> +          scale = 1 << INTVAL (scale_rtx);
>>             break;
>>           default:
>>             return false;
>> @@ -3484,6 +3593,14 @@ csky_print_operand (FILE *stream, rtx x, int 
>> code)
>>       case UNSPEC:
>>         csky_output_pic_addr_const (stream, x, code);
>>         break;
>> +    case CONST_DOUBLE:
>> +      {
>> +        char fpstr[20];
>> +        real_to_decimal ( fpstr, CONST_DOUBLE_REAL_VALUE (x),
>> +                 sizeof (fpstr), 0, 1);
>> +        fprintf (stream, "%s", fpstr);
>> +      }
>> +      break;
>>       default:
>>         output_addr_const (stream, x);
>>         break;
>> @@ -3997,17 +4114,37 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, 
>> rtx operands[],
>>           return "mfhi\t%0";
>>           }
>>   -        if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
>> -          return "fmovs\t%0, %1";
>> -        if (CSKY_VREG_P (dstreg))
>> -          return "fmtvrl\t%0, %1";
>> -        if (CSKY_VREG_P (srcreg))
>> -          return "fmfvrl\t%0, %1";
>> -
>> -        if (REGNO (src) == CSKY_CC_REGNUM)
>> -          return "mvc\t%0";
>> -        else
>> -          return "mov\t%0, %1";
>> +      if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
>> +        {
>> +          if (CSKY_ISA_FEATURE (fpv2_sf))
>> +        return "fmovs\t%0, %1";
>> +          else if (CSKY_ISA_FEATURE (fpv3_sf))
>> +        return "fmov.32\t%0, %1";
>> +          else
>> +        gcc_unreachable ();
>> +        }
>> +      if (CSKY_VREG_P (dstreg))
>> +        {
>> +          if (CSKY_ISA_FEATURE (fpv2_sf))
>> +        return "fmtvrl\t%0, %1";
>> +          else if (CSKY_ISA_FEATURE (fpv3_sf))
>> +        return "fmtvr.32.1\t%0, %1";
>> +          else
>> +        gcc_unreachable ();
>> +        }
>> +      if (CSKY_VREG_P (srcreg))
>> +        {
>> +          if (CSKY_ISA_FEATURE (fpv2_sf))
>> +        return "fmfvrl\t%0, %1";
>> +          else if (CSKY_ISA_FEATURE (fpv3_sf))
>> +        return "fmfvr.32.1\t%0, %1";
>> +          else
>> +        gcc_unreachable ();
>> +        }
>> +      if (REGNO (src) == CSKY_CC_REGNUM)
>> +        return "mvc\t%0";
>> +      else
>> +        return "mov\t%0, %1";
>>       }
>>         /* The situation mov memory to reg.  */
>>         else if (GET_CODE (src) == MEM)
>> @@ -4018,13 +4155,21 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, 
>> rtx operands[],
>>           switch (GET_MODE (src))
>>             {
>>             case E_HImode:
>> +          case E_HFmode:
>>           return "ldr.h\t%0, %1";
>>             case E_QImode:
>>           return "ldr.b\t%0, %1";
>>             case E_SImode:
>>             case E_SFmode:
>>           if (CSKY_VREG_P (REGNO (dst)))
>> -          return "fldrs\t%0, %1";
>> +          {
>> +            if (CSKY_ISA_FEATURE(fpv2_sf))
>> +              return "fldrs\t%0, %1";
>> +            else if (CSKY_ISA_FEATURE(fpv3_sf))
>> +              return "fldr.32\t%0, %1";
>> +            else
>> +              gcc_unreachable ();
>> +            }
>>           else
>>             return "ldr.w\t%0, %1";
>>             default:
>> @@ -4042,13 +4187,21 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, 
>> rtx operands[],
>>           switch (GET_MODE (src))
>>             {
>>             case E_HImode:
>> +          case E_HFmode:
>>           return "ld.h\t%0, %1";
>>             case E_QImode:
>>           return "ld.b\t%0, %1";
>>             case E_SFmode:
>>             case E_SImode:
>>           if (CSKY_VREG_P (REGNO (dst)))
>> -          return "flds\t%0, %1";
>> +          {
>> +             if (CSKY_ISA_FEATURE(fpv2_sf))
>> +               return "flds\t%0, %1";
>> +             else if (CSKY_ISA_FEATURE(fpv3_sf))
>> +               return "fld.32\t%0, %1";
>> +             else
>> +               gcc_unreachable ();
>> +           }
>>           else
>>             return "ld.w\t%0, %1";
>>             default:
>> @@ -4106,7 +4259,14 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, 
>> rtx operands[],
>>         case E_SFmode:
>>         case E_SImode:
>>           if (CSKY_VREG_P (REGNO (src)))
>> -          return "fstrs\t%1, %0";
>> +          {
>> +        if (CSKY_ISA_FEATURE(fpv2_sf))
>> +          return "fstrs\t%1, %0";
>> +        else if (CSKY_ISA_FEATURE(fpv3_sf))
>> +          return "fstr.32\t%1, %0";
>> +        else
>> +          gcc_unreachable ();
>> +          }
>>           else
>>             return "str.w\t%1, %0";
>>         default:
>> @@ -4122,7 +4282,14 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, 
>> rtx operands[],
>>         case E_SImode:
>>         case E_SFmode:
>>           if (CSKY_VREG_P (REGNO (src)))
>> -          return "fsts\t%1, %0";
>> +          {
>> +        if (CSKY_ISA_FEATURE(fpv2_sf))
>> +          return "fsts\t%1, %0";
>> +        else if (CSKY_ISA_FEATURE(fpv3_sf))
>> +          return "fst.32\t%1, %0";
>> +        else
>> +          gcc_unreachable ();
>> +          }
>>           else
>>             return "st.w\t%1, %0";
>>         default:
>> @@ -4261,7 +4428,14 @@ csky_output_movedouble (rtx operands[],
>>           return "mthi\t%R1\n\tmtlo\t%1";
>>           }
>>         else if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
>> -        return "fmovd\t%0, %1";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +        return "fmovd\t%0, %1";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +        return "fmov.64\t%0, %1";
>> +          else
>> +        gcc_unreachable ();
>> +        }
>>         else if (CSKY_VREG_P (srcreg))
>>           {
>>             /* Since the vector registers in fpuv2_soft processors
>> @@ -4270,18 +4444,46 @@ csky_output_movedouble (rtx operands[],
>>             if (TARGET_SOFT_FPU)
>>             return "fmfvrl\t%0, %1";
>>             else if (TARGET_BIG_ENDIAN)
>> -        return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +            return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +            return "fmfvr.64\t%R0, %0, %1";
>> +          else
>> +            gcc_unreachable ();
>> +        }
>>             else
>> -        return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +            return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +            return "fmfvr.64\t%0, %R0, %1";
>> +          else
>> +            gcc_unreachable ();
>> +        }
>>           }
>>         else if (CSKY_VREG_P (dstreg))
>>           {
>>             if (TARGET_SOFT_FPU)
>>           return "fmtvrl\t%0, %1";
>>             else if (TARGET_BIG_ENDIAN)
>> -        return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +            return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +            return "fmtvr.64\t%0, %R1, %1";
>> +          else
>> +            gcc_unreachable ();
>> +        }
>>             else
>> -        return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +            return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +            return "fmtvr.64\t%0, %1, %R1";
>> +          else
>> +            gcc_unreachable ();
>> +        }
>>           }
>>           /* Ensure the second source not overwritten.  */
>> @@ -4323,9 +4525,23 @@ csky_output_movedouble (rtx operands[],
>>         if (CSKY_VREG_P (dstreg))
>>           {
>>             if (op0.index)
>> -        return "fldrd\t%0, %1";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +            return "fldrd\t%0, %1";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +            return "fldr.64\t%0, %1";
>> +          else
>> +            gcc_unreachable ();
>> +        }
>>             else
>> -        return "fldd\t%0, %1";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +            return "fldd\t%0, %1";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +            return "fld.64\t%0, %1";
>> +          else
>> +            gcc_unreachable ();
>> +        }
>>           }
>>         /* FIXME length attribute is wrong here.  */
>>         if (dstreg == basereg)
>> @@ -4389,9 +4605,23 @@ csky_output_movedouble (rtx operands[],
>>         if (CSKY_VREG_P (srcreg))
>>       {
>>         if (op0.index)
>> -        return "fstrd\t%1, %0";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +        return "fstrd\t%1, %0";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +        return "fstr.64\t%1, %0";
>> +          else
>> +        gcc_unreachable ();
>> +        }
>>         else
>> -        return "fstd\t%1, %0";
>> +        {
>> +          if (CSKY_ISA_FEATURE(fpv2_df))
>> +        return "fstd\t%1, %0";
>> +          else if (CSKY_ISA_FEATURE(fpv3_df))
>> +        return "fst.64\t%1, %0";
>> +          else
>> +        gcc_unreachable ();
>> +        }
>>       }
>>         /* FIXME length attribute is wrong here.  */
>>         if (srcreg == basereg)
>> @@ -4518,9 +4748,181 @@ csky_output_ck801_movedouble (rtx operands[],
>>       gcc_unreachable ();
>>   }
>>   +/* Calculate the instruction's length for moving double-word 
>> data.  */
>> +
>> +int
>> +csky_get_movedouble_length(rtx operands[])
>> +{
>> +  rtx dst = operands[0];
>> +  rtx src = operands[1];
>> +
>> +  if (REG_P (dst))
>> +    {
>> +      if (REG_P (src))
>> +    {
>> +      int dstreg = REGNO (dst);
>> +      int srcreg = REGNO (src);
>> +
>> +      if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
>> +        return 4;
>> +      else
>> +        return 8;
>> +    }
>> +      else if (GET_CODE (src) == MEM)
>> +    {
>> +      rtx memexp = XEXP (src, 0);
>> +      int dstreg = REGNO (dst);
>> +      struct csky_address op0;
>> +      decompose_csky_address (XEXP (src, 0), &op0);
>> +
>> +      if (GET_CODE (memexp) == LABEL_REF)
>> +        return 8;
>> +      if (CSKY_VREG_P (dstreg))
>> +        return 4;
>> +      return 8;
>> +    }
>> +      else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == 
>> CONST_DOUBLE)
>> +    {
>> +      split_double (src, operands + 2, operands + 3);
>> +      if (CSKY_CONST_OK_FOR_N (INTVAL (operands[2]) + 1)
>> +          && CSKY_CONST_OK_FOR_N (INTVAL (operands[3]) + 1)
>> +          && REGNO (operands[0]) < 6)
>> +        return 4;
>> +      else
>> +        return 8;
>> +    }
>> +    }
>> +  else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
>> +    {
>> +      rtx memexp = XEXP (dst, 0);
>> +      int srcreg = REGNO (src);
>> +      int offset = -1;
>> +      if (CSKY_VREG_P (srcreg))
>> +    return 4;
>> +
>> +      if (GET_CODE (memexp) == REG)
>> +    offset = 0;
>> +      else if (GET_CODE (memexp) == PLUS)
>> +    {
>> +      if (GET_CODE (XEXP (memexp, 0)) == REG)
>> +        offset = INTVAL (XEXP (memexp, 1));
>> +      else if (GET_CODE (XEXP (memexp, 1)) == REG)
>> +        offset = INTVAL (XEXP (memexp, 0));
>> +      else
>> +        gcc_unreachable ();
>> +    }
>> +      else
>> +    gcc_unreachable ();
>> +
>> +      if (srcreg <= 6 && offset <= 1020)
>> +    return 4;
>> +      else if ((srcreg == 7 && offset <= 1024) || (srcreg <= 7 && 
>> offset == 1024))
>> +    return 6;
>> +      else
>> +    return 8;
>> +    }
>> +  else
>> +    gcc_unreachable ();
>> +
>> +  return 0;
>> +}
>> +
>> +/* Output float point load/store instructions for fpuv3.  */
>> +
>> +const char *
>> +fpuv3_output_move (rtx *operands)
>> +{
>> +  rtx reg, mem, addr, ops[2];
>> +  bool isload = REG_P (operands[0]);
>> +
>> +  const char *templ = "f%s%s.%s\t%%0, %%1";
>> +  char buff[50];
>> +  machine_mode mode;
>> +
>> +  reg = operands[isload ? 0 : 1];
>> +  mem = operands[isload ? 1 : 0];
>> +
>> +  gcc_assert (REG_P (reg));
>> +  gcc_assert (CSKY_VREG_P (REGNO (reg)));
>> +  gcc_assert (MEM_P (mem));
>> +
>> +  mode = GET_MODE (reg);
>> +  const char *type = mode == DFmode ? "64" :
>> +             mode == SFmode ? "32" :
>> +             mode == HFmode ? "16" :
>> +             NULL;
>> +  gcc_assert(type != NULL);
>> +
>> +  addr = XEXP (mem, 0);
>> +  struct csky_address caddr;
>> +  decompose_csky_address (addr, &caddr);
>> +
>> +  ops[0] = reg;
>> +  ops[1] = mem;
>> +  sprintf (buff, templ,
>> +       isload ? "ld" : "st",
>> +       caddr.index ? "r" : "",
>> +       type);
>> +  output_asm_insn (buff, ops);
>> +
>> +  return "";
>> +}
>> +
>> +/* Check if a const_double can be used by a VFP fmovi instruction.  */
>> +
>> +int
>> +fpuv3_const_double_rtx (rtx x)
>> +{
>> +  REAL_VALUE_TYPE r, m;
>> +  r = *CONST_DOUBLE_REAL_VALUE (x);
>> +
>> +  /* Fpuv3 doesn't support the following values.  */
>> +  if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r) || 
>> REAL_VALUE_MINUS_ZERO (r)
>> +      || r.cl == rvc_zero)
>> +    return 0;
>> +
>> +  /* Extract sign, exponent and mantissa.  */
>> +  int exponent;
>> +  r = real_value_abs (&r);
>> +  exponent = REAL_EXP (&r);
>> +
>> +  bool fail;
>> +  unsigned HOST_WIDE_INT mantissa, mant_hi;
>> +  unsigned HOST_WIDE_INT mask;
>> +  int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1;
>> +  real_ldexp (&m, &r, point_pos - exponent);
>> +  wide_int w = real_to_integer (&m, &fail, HOST_BITS_PER_WIDE_INT * 2);
>> +  mantissa = w.elt (0);
>> +  mant_hi = w.elt (1);
>> +
>> +  exponent -= 1;
>> +
>> +  if (!IN_RANGE (exponent, -4, 11))
>> +    return 0;
>> +
>> +  /* If there are bits set in the low part of the mantissa, these 
>> values are
>> +     not supported.  */
>> +  if (mantissa != 0)
>> +    return 0;
>> +
>> +  /* Now, make the mantissa contain the most-significant bits, and the
>> +     point_pos indicates the number of these bits.  */
>> +  point_pos -= HOST_BITS_PER_WIDE_INT;
>> +  mantissa = mant_hi;
>> +
>> +  /* We can only allow a mantissa of 9 significant digits, top of 
>> which is always 1.  */
>> +  mask = ((unsigned HOST_WIDE_INT)1 << (point_pos - 9)) - 1;
>> +  if ((mantissa & mask) != 0)
>> +    return 0;
>> +
>> +  return 1;
>> +}
>> +
>> +
>>   /* Split operands for an AND expression when OPERANDS[2] is a 
>> constant.
>>      Note operands[0] is marked earlyclobber in this case and can be
>>      overwritten.  Return true if "DONE", false otherwise.  */
>> +
>>   bool
>>   csky_split_and (rtx *operands)
>>   {
>> @@ -4650,6 +5052,7 @@ csky_split_and (rtx *operands)
>>   /* Split operands for an IOR expression when OPERANDS[2] is a 
>> constant.
>>      Note operands[0] is marked earlyclobber in this case and can be
>>      overwritten.  Return true if "DONE", false otherwise.  */
>> +
>>   bool
>>   csky_split_ior (rtx *operands)
>>   {
>> @@ -4717,6 +5120,7 @@ csky_split_ior (rtx *operands)
>>   /* Split operands for an XOR expression when OPERANDS[2] is a 
>> constant.
>>      Note operands[0] is marked earlyclobber in this case and can be
>>      overwritten.  Return true if "DONE", false otherwise.  */
>> +
>>   bool
>>   csky_split_xor (rtx *operands)
>>   {
>> @@ -4765,6 +5169,7 @@ csky_split_xor (rtx *operands)
>>       /* Return true if X is an address form involving a symbol or 
>> label ref.  */
>> +
>>   bool
>>   csky_symbolic_address_p (rtx x)
>>   {
>> @@ -4793,6 +5198,9 @@ csky_emit_compare (enum rtx_code code, rtx op0, 
>> rtx op1)
>>     bool invert;
>>     rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
>>   +  if (GET_MODE_CLASS(GET_MODE (op0)) == MODE_FLOAT)
>> +    return csky_emit_compare_float(code, op0, op1);
>> +
>>     if (GET_CODE (op1) == CONST_INT)
>>       {
>>         HOST_WIDE_INT val = INTVAL (op1);
>> @@ -5707,6 +6115,7 @@ tls_unspec_mentioned_p (rtx x)
>>       /* Implement LEGITIMATE_PIC_OPERAND_P.  */
>> +
>>   bool
>>   csky_legitimate_pic_operand_p (rtx x)
>>   {
>> @@ -5938,33 +6347,20 @@ csky_emit_compare_float (enum rtx_code code, 
>> rtx op0, rtx op1)
>>       op1 = force_reg (mode, op1);
>>       invert = false;
>> +
>>     switch (code)
>>       {
>>       case EQ:
>>         code = NE;
>>         invert = true;
>>         break;
>> -
>> -    case NE:
>> -      break;
>> -    case LE:
>> -      if (op1 == CONST0_RTX (mode))
>> -    op1 = force_reg (mode, op1);
>> -      break;
>>       case GT:
>> -      if (op1 == CONST0_RTX (mode))
>> -    op1 = force_reg (mode, op1);
>> -      break;
>> -    case GE:
>> -      break;
>>       case LT:
>> -      if (op1 == CONST0_RTX (mode))
>> -    {
>> -      code = GE;
>> -      invert = true;
>> -    }
>> -      break;
>> -    case UNORDERED:
>> +    case LE:
>> +      if (op1 == CONST0_RTX (mode) && (CSKY_ISA_FEATURE_GET(fpv2_sf)
>> +                       || CSKY_ISA_FEATURE_GET(fpv2_df)
>> +                       || CSKY_ISA_FEATURE_GET(fpv2_divd)))
>> +    op1 = force_reg (mode, op1);
>>         break;
>>       case ORDERED:
>>         code = UNORDERED;
>> @@ -5980,10 +6376,11 @@ csky_emit_compare_float (enum rtx_code code, 
>> rtx op0, rtx op1)
>>     return invert;
>>   }
>>   -/* Support for the Q memory constraint.  Returns true if OP is a 
>> MEM RTX
>> -   with an address consisting of base + index or base + 
>> displacement.  */
>> +/* Support for the Q or W memory constraint.  Returns true if OP is 
>> a MEM
>> +   RTX with an address consisting of base + index or base + 
>> displacement.  */
>> +
>>   bool
>> -csky_valid_fpuv2_mem_operand (rtx op)
>> +csky_valid_mem_constraint_operand (rtx op, const char *constraint)
>>   {
>>     struct csky_address addr;
>>   @@ -5998,7 +6395,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
>>       return false;
>>       /* Verify index operand. */
>> -  if (addr.index)
>> +  if (addr.index && (constraint[0] == 'Q' || constraint[0] == 'W'))
>>       {
>>         if (!is_csky_address_register_rtx_p (addr.index, 0))
>>       return false;
>> @@ -6010,7 +6407,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
>>         return false;
>>       }
>>     /* Verify disp operand.  */
>> -  else if (addr.disp)
>> +  else if (addr.disp && constraint[0] == 'Q')
>>       {
>>         rtx disp = addr.disp;
>>   @@ -6023,7 +6420,11 @@ csky_valid_fpuv2_mem_operand (rtx op)
>>            return false;
>>       }
>> -  return true;
>> +  else if (constraint[0] == 'Q')
>> +  /* Single reg is valid for 'Q'.  */
>> +    return true;
>> +
>> +  return false;
>>   }
>>     @@ -6442,7 +6843,7 @@ ck803_rtx_costs (rtx x, int code, int 
>> outer_code ATTRIBUTE_UNUSED,
>>       }
>>   }
>>   -/* TARGET_RTX_COSTS helper for ck807+ arches.  */
>> +/* TARGET_RTX_COSTS helper for ck807/ck810 arches.  */
>>     static bool
>>   ck807_ck810_rtx_costs (rtx x, int code,
>> @@ -6473,6 +6874,52 @@ ck807_ck810_rtx_costs (rtx x, int code,
>>       }
>>   }
>>   +/* TARGET_RTX_COSTS helper for ck860 arches.  */
>> +
>> +static bool
>> +ck860_rtx_costs (rtx x, int code, machine_mode mode,
>> +         int outer_code ATTRIBUTE_UNUSED,
>> +         int *total, bool speed ATTRIBUTE_UNUSED)
>> +{
>> +  switch (code)
>> +    {
>> +    case PLUS:
>> +      /* The costs of mula is 1 more than mult.  */
>> +      if (GET_CODE (XEXP (x, 0)) == MULT && REG_P (XEXP (x, 1)) && 
>> speed)
>> +    {
>> +      rtx mul_op0 = XEXP (XEXP (x, 0), 0);
>> +      rtx mul_op1 = XEXP (XEXP (x, 0), 1);
>> +      if (REG_P (mul_op0) && REG_P (mul_op1))
>> +        {
>> +          *total = COSTS_N_INSNS (1);
>> +          *total += rtx_cost (XEXP (x, 0), mode,
>> +                  (enum rtx_code) code, 0, speed);
>> +          return true;
>> +        }
>> +    }
>> +      return false;
>> +    case MULT:
>> +      if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
>> +    {
>> +      HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
>> +      if (val % 2 == 0 && val < 0xffffffff && val > 0)
>> +        {
>> +          *total = COSTS_N_INSNS (1);
>> +          return true;
>> +        }
>> +    }
>> +      return false;
>> +
>> +    case CONST:
>> +    case LABEL_REF:
>> +    case SYMBOL_REF:
>> +      *total = COSTS_N_INSNS (3);
>> +      return true;
>> +    default:
>> +      return false;
>> +    }
>> +}
>> +
>>     /* Implement TARGET_RTX_COSTS, to compute a (partial) cost for 
>> rtx X.
>>      Return true if the complete cost has been computed, and false if
>> @@ -6491,6 +6938,8 @@ csky_rtx_costs (rtx x, machine_mode mode 
>> ATTRIBUTE_UNUSED, int outer_code,
>>       return ck803_rtx_costs (x, code, outer_code, total, speed);
>>     else if (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
>>       return ck807_ck810_rtx_costs (x, code, outer_code, total, speed);
>> +  else if (CSKY_TARGET_ARCH (CK860))
>> +    return ck860_rtx_costs (x, code, mode, outer_code, total, speed);
>>     else
>>       gcc_unreachable ();
>>   }
>> @@ -6633,6 +7082,7 @@ csky_warn_func_return (tree decl)
>>   /* Implement TARGET_RETURN_IN_MEMORY to decide whether TYPE should be
>>      returned in memory (true) or in a register (false).
>>      FNTYPE is the type of the function making the call.  */
>> +
>>   static bool
>>   csky_return_in_memory (const_tree type,
>>                  const_tree fntype ATTRIBUTE_UNUSED)
>> @@ -6646,6 +7096,7 @@ csky_return_in_memory (const_tree type,
>>      Dwarf models VFP registers as  64-bit or 128-bit registers default.
>>      GCC models tham as 32-bit registers, so we need to describe this to
>>      the DWARF generation code.  Other registers can use the 
>> default.  */
>> +
>>   static rtx
>>   csky_dwarf_register_span (rtx rtl)
>>   {
>> @@ -6659,11 +7110,15 @@ csky_dwarf_register_span (rtx rtl)
>>     if (!CSKY_VREG_P (regno))
>>       return NULL_RTX;
>>   +  if (CSKY_VREG_HI_P (regno))
>> +    regno += 16;
>> +
>>     mode = GET_MODE (rtl);
>>     if (GET_MODE_SIZE (mode) < 8)
>>       return NULL_RTX;
>>   -  if (TARGET_SOFT_FPU)
>> +
>> +  if (TARGET_SINGLE_FPU)
>>       {
>>         nregs = GET_MODE_SIZE (mode) / 4;
>>         for (i = 0; i < nregs; i += 2)
>> @@ -6684,9 +7139,18 @@ csky_dwarf_register_span (rtx rtl)
>>        as the CPU bit width. Transform the 64-bit FPU registers to
>>        32 bits here, and we will modify the unwind processing to
>>        fit CSKY architecture later.  */
>> -      nregs = GET_MODE_SIZE (mode) / 8;
>> -      for (i = 0; i < nregs; i++)
>> -    parts[i] = gen_rtx_REG (SImode, regno + i);
>> +      nregs = GET_MODE_SIZE (mode) / 4;
>> +      for (i = 0; i < nregs; i += 2)
>> +    if (TARGET_BIG_ENDIAN)
>> +      {
>> +        parts[i] = gen_rtx_REG (SImode, regno + i - 16);
>> +        parts[i + 1] = gen_rtx_REG (SImode, regno + i);
>> +      }
>> +    else
>> +      {
>> +        parts[i] = gen_rtx_REG (SImode, regno + i);
>> +        parts[i + 1] = gen_rtx_REG (SImode, regno + i - 16);
>> +      }
>>       }
>>       return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nregs , parts));
>> @@ -6847,6 +7311,34 @@ csky_init_cumulative_args (CUMULATIVE_ARGS 
>> *pcum, tree fntype,
>>       pcum->is_stdarg = true;
>>   }
>>   +
>> +/* Implement the TARGET_INIT_BUILTINS target macro.  */
>> +
>> +void
>> +csky_init_builtins (void)
>> +{
>> +  /* Inint fp16.  */
>> +  static tree csky_floatHF_type_node = make_node (REAL_TYPE);
>> +  TYPE_PRECISION (csky_floatHF_type_node) = GET_MODE_PRECISION 
>> (HFmode);
>> +  layout_type (csky_floatHF_type_node);
>> +  (*lang_hooks.types.register_builtin_type) (csky_floatHF_type_node, 
>> "__fp16");
>> +}
>> +
>> +
>> +/* Implement TARGET_MANGLE_TYPE.  */
>> +
>> +static const char *
>> +csky_mangle_type (const_tree type)
>> +{
>> +  if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
>> +      && DECL_NAME (TYPE_NAME (type))
>> +      && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), 
>> "__fp16"))
>> +    return "__fp16";
>> +
>> +  /* Use the default mangling.  */
>> +  return NULL;
>> +}
>> +
>>   struct gcc_target targetm = TARGET_INITIALIZER;
>>     #include "gt-csky.h"
>> diff --git a/gcc/config/csky/csky.h b/gcc/config/csky/csky.h
>> index c7590ab..f535c42 100644
>> --- a/gcc/config/csky/csky.h
>> +++ b/gcc/config/csky/csky.h
>> @@ -28,8 +28,17 @@
>>   #define CSKY_GENERAL_REGNO_P(N)            \
>>     ((N) < CSKY_NGPR_REGS && (int)(N) >= 0)
>>   -#define CSKY_VREG_P(N)             \
>> -  ((N) >= CSKY_FIRST_VFP_REGNUM && (N) <= CSKY_LAST_VFP_REGNUM)
>> +#define CSKY_VREG_LO_P(N) \
>> +  ((N) >= CSKY_FIRST_VFP_REGNUM \
>> +   && (N) <= CSKY_LAST_VFP_REGNUM)
>> +
>> + #define CSKY_VREG_HI_P(N) \
>> +   ((N) >= CSKY_FIRST_VFP3_REGNUM \
>> +    && (N) <= CSKY_LAST_VFP3_REGNUM)
>> +
>> + #define CSKY_VREG_P(N)    \
>> +   (CSKY_VREG_LO_P(N)     \
>> +    || CSKY_VREG_HI_P(N))
>>     #define CSKY_HILO_REG_P(N)   \
>>     ((N) == CSKY_HI_REGNUM || (N) == CSKY_LO_REGNUM)
>> @@ -124,7 +133,7 @@
>>     (optimize_size && TARGET_CONSTANT_POOL \
>>      && (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802)))
>>   #define TARGET_TLS \
>> -  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
>> +  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810) || 
>> CSKY_TARGET_ARCH (CK860))
>>     /* Run-time Target Specification.  */
>>   #define TARGET_SOFT_FLOAT       (csky_float_abi == 
>> CSKY_FLOAT_ABI_SOFT)
>> @@ -133,7 +142,9 @@
>>   /* Use hardware floating point calling convention.  */
>>   #define TARGET_HARD_FLOAT_ABI   (csky_float_abi == 
>> CSKY_FLOAT_ABI_HARD)
>>   -#define TARGET_SINGLE_FPU     (csky_fpu_index == TARGET_FPU_fpv2_sf)
>> +#define TARGET_SINGLE_FPU     (csky_fpu_index == TARGET_FPU_fpv2_sf \
>> +                   || csky_fpu_index == TARGET_FPU_fpv3_hsf \
>> +                   || csky_fpu_index == TARGET_FPU_fpv3_hf)
>>   #define TARGET_DOUBLE_FPU     (TARGET_HARD_FLOAT && 
>> !TARGET_SINGLE_FPU)
>>     #define FUNCTION_VARG_REGNO_P(REGNO)      \
>> @@ -142,13 +153,18 @@
>>           CSKY_FIRST_VFP_REGNUM + CSKY_NPARM_FREGS - 1))
>>     #define CSKY_VREG_MODE_P(mode) \
>> -  ((mode) == SFmode || (mode) == DFmode)
>> +  ((mode) == SFmode || (mode) == DFmode \
>> +   || (CSKY_ISA_FEATURE(fpv3_hf) && (mode) == HFmode))
>>     #define FUNCTION_VARG_MODE_P(mode)  \
>>     (TARGET_HARD_FLOAT_ABI            \
>>      && CSKY_VREG_MODE_P(mode)        \
>>      && !(mode == DFmode && TARGET_SINGLE_FPU))
>>   +#define TARGET_SUPPORT_FPV3 (CSKY_ISA_FEATURE (fpv3_hf)    \
>> +                 || CSKY_ISA_FEATURE (fpv3_sf) \
>> +                 || CSKY_ISA_FEATURE (fpv3_df))
>> +
>>   /* Number of loads/stores handled by ldm/stm.  */
>>   #define CSKY_MIN_MULTIPLE_STLD    3
>>   #define CSKY_MAX_MULTIPLE_STLD    12
>> @@ -427,7 +443,7 @@ typedef struct
>> ******************************************************************/
>>     -#define FIRST_PSEUDO_REGISTER 71
>> +#define FIRST_PSEUDO_REGISTER 202
>>     /* 1 for registers that have pervasive standard uses
>>      and are not available for the register allocator.
>> @@ -456,7 +472,31 @@ typedef struct
>>    /*  reserved */                            \
>>        1,       1,                                \
>>    /*  epc */                                \
>> -     1                                    \
>> +     1,                                    \
>> + /* vr16  vr17  vr18  vr19  vr20  vr21  vr22  vr23 */            \
>> +     0,    0,    0,    0,    0,    0,    0,    0,            \
>> + /* vr24  vr25  vr26  vr27  vr28  vr29  vr30  vr31 */            \
>> +     0,    0,    0,    0,    0,    0,    0,    0 ,            \
>> + /* reserved */                                \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> + /* reserved */                                \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +                                    \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +                                    \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +                                    \
>> +     1,    1,    1                            \
>>   }
>>     /* Like `CALL_USED_REGISTERS' but used to overcome a historical
>> @@ -487,7 +527,31 @@ typedef struct
>>    /*  reserved */                            \
>>        1,       1,                                \
>>    /*  epc */                                \
>> -     1                                    \
>> +     1,                                    \
>> + /*  vr16  vr17  vr18  vr19  vr20  vr21  vr22 vr23*/            \
>> +     1,       1,     1,    1,    1,       1,     1, 1,            \
>> + /*  vr24  vr25 vr26  vr27  vr28  vr29     vr30  vr31 */            \
>> +     1,       1,     1,    1,    1,       1,     1, 1,            \
>> + /*  reserved */                            \
>> +     1,       1,     1,    1,    1,       1,     1, 1,            \
>> +     1,       1,     1,    1,    1,       1,     1, 1,            \
>> + /* reserved */                                \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +                                    \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +                                    \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +     1,    1,    1,    1,    1,    1,    1,    1,            \
>> +                                    \
>> +     1,    1,    1                            \
>>   }
>>     #define REGISTER_NAMES                            \
>> @@ -510,7 +574,37 @@ typedef struct
>>     "vr0", "vr1", "vr2",    "vr3",    "vr4",    "vr5", "vr6",    
>> "vr7",        \
>>     "vr8", "vr9", "vr10", "vr11", "vr12", "vr13", "vr14", 
>> "vr15",        \
>>     "reserved", "reserved",                        \
>> -  "epc"                                    \
>> +  "epc",                                \
>> +  /* V registers: 71~86 */                        \
>> +  "vr16", "vr17", "vr18", "vr19", "vr20", "vr21", "vr22", "vr23",    \
>> +  "vr24", "vr25", "vr26", "vr27", "vr28", "vr29", "vr30", "vr31",    \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved",                                \
>> +  /* reserved: 87~201*/                            \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved",                        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved",                        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved", "reserved", "reserved", "reserved",        \
>> +  "reserved", "reserved",                        \
>> +  "reserved", "reserved", "reserved"                    \
>>   }
>>     /* Table of additional register names to use in user input. */
>> @@ -569,9 +663,16 @@ typedef struct
>>        52,   53,     54,   55,   56,   57,     58,   59, \
>>   /*  vr8      vr9    vr10  vr11  vr12  vr13    vr14  vr15 */        \
>>        60,   61,     62,   63,   64,   65,     66,   67, \
>> +/*  vr16  vr17  vr18  vr18  vr20  vr21    vr22  vr23 */ \
>> +     71,   72,     73,   74,   75,   76,     77,   78,        \
>> +/*  vr24  vr25    vr26  vr27  vr28  vr28    vr30  vr31 */        \
>> +     79,   80,     81,   82,   83,   84,     85,   86,        \
>>   /*  reserved  */                        \
>>        36,   37,     38,   39,   40,   41,     42,   43, \
>>        44,   45,     46,   47,   48,   49,     50,   51, \
>> +/*  reserved  */                        \
>> +     87,   88,     89,   90,   91,   92,     93,   94,        \
>> +     95,   96,     97,   98,   99,   100,  101,  102,        \
>>   /*  sp      tls    reserved     c       reserved        epc */    \
>>        14,   31,     32,         33,   68,     69, 70     }
>>   @@ -616,21 +717,34 @@ enum reg_class
>>     /* Define which registers fit in which classes.  This is an 
>> initializer
>>      for a vector of HARD_REG_SET of length N_REG_CLASSES.  */
>> -#define REG_CLASS_CONTENTS                         \
>> -{                                     \
>> -  {0x00000000, 0x00000000, 0x00000000 },  /* NO_REGS */    \
>> -  {0x000000FF, 0x00000000, 0x00000000 },  /* MINI_REGS           
>> */    \
>> -  {0x00004000, 0x00000000, 0x00000000 },  /* SP_REGS */    \
>> -  {0x0000FFFF, 0x00000000, 0x00000000 },  /* LOW_REGS */    \
>> -  {0xFFFFFFFF, 0x00000000, 0x00000000 },  /* GENERAL_REGS */    \
>> -  {0x00000000, 0x00000002, 0x00000000 },  /* C_REGS */    \
>> -  {0x00000000, 0x00000004, 0x00000000 },  /* HI_REG */    \
>> -  {0x00000000, 0x00000008, 0x00000000 },  /* LO_REG */    \
>> -  {0x00000000, 0x0000000c, 0x00000000 },  /* HILO_REGS           
>> */    \
>> -  {0x00000000, 0xFFF00000, 0x0000000F },  /* V_REGS */    \
>> -  {0x00000000, 0x00000000, 0x00000040 },  /* OTHER_REGS           
>> */    \
>> -  {0x00000000, 0x0FF00001, 0x00000030 },  /* RESERVE_REGS */    \
>> -  {0xFFFFFFFF, 0xFFFFFFFF, 0x0000007F },  /* ALL_REGS */    \
>> +#define REG_CLASS_CONTENTS                              \
>> +{                                          \
>> +  {0x00000000, 0x00000000, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* NO_REGS     
>> */   \
>> +  {0x000000FF, 0x00000000, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* MINI_REGS     
>> */   \
>> +  {0x00004000, 0x00000000, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* SP_REGS     
>> */   \
>> +  {0x0000FFFF, 0x00000000, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* LOW_REGS      
>> */   \
>> +  {0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* GENERAL_REGS  
>> */   \
>> +  {0x00000000, 0x00000002, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* C_REGS     */   \
>> +  {0x00000000, 0x00000004, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* HI_REG     */   \
>> +  {0x00000000, 0x00000008, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* LO_REG     */   \
>> +  {0x00000000, 0x0000000c, 0x00000000, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* HILO_REGS     
>> */   \
>> +  {0x00000000, 0xFFF00000, 0x007FFF8F, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* V_REGS     */   \
>> +  {0x00000000, 0x00000000, 0x00000040, 0x00000000,                  \
>> +   0x00000000, 0x00000000, 0x00000000},            /* OTHER_REGS    
>> */   \
>> +  {0x00000000, 0x000FFFF1, 0xFF800030, 0xFFFFFFFF,                  \
>> +   0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF},            /* RESERVE_REGS  
>> */   \
>> +  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,                  \
>> +   0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF},            /* ALL_REGS      
>> */   \
>>   }
>>     /* Return register class from regno.  */
>> diff --git a/gcc/config/csky/csky.md b/gcc/config/csky/csky.md
>> index 8bb3b2b..c27d627 100644
>> --- a/gcc/config/csky/csky.md
>> +++ b/gcc/config/csky/csky.md
>> @@ -32,6 +32,8 @@
>>      (CSKY_FIRST_RET_REGNUM        0)
>>      (CSKY_FIRST_VFP_REGNUM        52)
>>      (CSKY_LAST_VFP_REGNUM        67)
>> +   (CSKY_FIRST_VFP3_REGNUM        71)
>> +   (CSKY_LAST_VFP3_REGNUM        86)
>>      (CSKY_FIRST_HIGH_REGNUM        16)
>>      (CSKY_LAST_HIGH_REGNUM        31)
>>      (CSKY_FIRST_MINI_REGNUM        0)
>> @@ -423,85 +425,6 @@
>>      (set_attr "type" "alu,alu,alu,load,load,store")]
>>   )
>>   -;; Float mov instructions.
>> -
>> -(define_expand "movsf"
>> -  [(set (match_operand:SF 0 "general_operand" "")
>> -    (match_operand:SF 1 "general_operand" ""))]
>> -  ""
>> -  "
>> -  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
>> -    operands[1] = force_reg (SFmode, operands[1]);
>> -  "
>> -)
>> -
>> -;; FIXME: maybe the vreg load/stores should have their own type attr.
>> -(define_insn "*csky_movsf_fpv2"
>> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,v,r,r,r, 
>> m,Q,v,v,v")
>> -    (match_operand:SF 1 "general_operand"       " 
>> b,r,r,v,m,mF,r,v,Q,v,m"))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "* return csky_output_move (insn, operands, SFmode);"
>> -  [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4")
>> -   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
>> -)
>> -
>> -(define_insn "*ck801_movsf"
>> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
>> -    (match_operand:SF 1 "general_operand"       " r,m,mF,r"))]
>> -  "CSKY_ISA_FEATURE (E1)"
>> -  "* return csky_output_ck801_move (insn, operands, SFmode);"
>> -  [(set_attr "length" "2,4,4,4")
>> -   (set_attr "type" "alu,load,load,store")]
>> -)
>> -
>> -(define_insn "*csky_movsf"
>> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
>> -    (match_operand:SF 1 "general_operand"       " b,r,m,mF,r"))]
>> -  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "* return csky_output_move (insn, operands, SFmode);"
>> - [(set_attr "length" "2,4,4,4,4")
>> -  (set_attr "type" "alu,alu,load,load,store")]
>> -)
>> -
>> -
>> -(define_expand "movdf"
>> -  [(set (match_operand:DF 0 "general_operand" "")
>> -    (match_operand:DF 1 "general_operand" ""))]
>> -  ""
>> -  "
>> -  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
>> -      operands[1] = force_reg (DFmode, operands[1]);
>> -  "
>> -)
>> -
>> -;; FIXME: maybe the vreg load/stores should have their own type attr.
>> -(define_insn "*csky_movdf_fpv2"
>> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,v,r,r,r, 
>> m,Q,v,v,v")
>> -    (match_operand:DF 1 "general_operand" "b,r,r,v,m,mF,r,v,Q,v,m"))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "* return csky_output_movedouble (operands, DFmode);"
>> -  [(set_attr "length" "4,8,8,8,8,8,8,8,8,8,8")
>> -   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
>> -)
>> -
>> -(define_insn "*ck801_movdf"
>> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
>> -    (match_operand:DF 1 "general_operand"       " r,m,mF,r"))]
>> -  "CSKY_ISA_FEATURE (E1)"
>> -  "* return csky_output_ck801_movedouble (operands, DFmode);"
>> -  [(set_attr "length" "4,8,8,8")
>> -   (set_attr "type" "alu,load,load,store")]
>> -)
>> -
>> -(define_insn "*csky_movdf"
>> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
>> -    (match_operand:DF 1 "general_operand"       " b,r,m,mF,r"))]
>> -  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_df)"
>> -  "* return csky_output_movedouble (operands, DFmode);"
>> - [(set_attr "length" "4,8,8,8,8")
>> -  (set_attr "type" "alu,alu,load,load,store")]
>> -)
>> -
>>   ;; The only CCmode move supported is a nop.  Without this pattern,
>>   ;; CSE is unable to eliminate redundant comparisons in conditional
>>   ;; execution expressions.
>> @@ -522,7 +445,7 @@
>>     (define_expand "movsicc"
>>     [(set (match_operand 0 "register_operand" "")
>> -    (if_then_else:SI (match_operand       1 
>> "ordered_comparison_operator" "")
>> +    (if_then_else:SI (match_operand       1 "comparison_operator" "")
>>                (match_operand:SI 2 "register_operand" "")
>>                (match_operand:SI 3 "register_operand" "")))]
>>     "CSKY_ISA_FEATURE (E2)"
>> @@ -1321,7 +1244,7 @@
>>     (define_expand "addsicc"
>>     [(match_operand:SI 0 "register_operand" "")
>> -   (match_operand    1 "ordered_comparison_operator" "")
>> +   (match_operand    1 "comparison_operator" "")
>>      (match_operand:SI 2 "register_operand" "")
>>      (match_operand:SI 3 "csky_literal_K_Uh_operand" "")]
>>     "CSKY_ISA_FEATURE (E2)"
>> @@ -3316,9 +3239,9 @@
>>     (define_expand "untyped_call"
>>     [(parallel [(call (match_operand 0 "" "")
>> -        (const_int 0))
>> -        (match_operand 1 "" "")
>> -        (match_operand 2 "" "")])]
>> +    (const_int 0))
>> +    (match_operand 1 "" "")
>> +    (match_operand 2 "" "")])]
>>     ""
>>   {
>>     int i;
>> @@ -3349,11 +3272,25 @@
>>     ""
>>     [(set_attr "length" "0")])
>>   -(define_insn "*call_value_internal_vs"
>> -  [(set (match_operand:SF               0 
>> "register_operand"          "=v,v,v")
>> +(define_insn "*call_value_internal_vh"
>> +  [(set (match_operand:HF               0 
>> "register_operand"          "=v,v,v")
>>           (call (mem:SI (match_operand:SI 1 
>> "csky_call_address_operand" "b, r,S"))
>>                 (match_operand 2 "" "")))
>>      (clobber (reg:SI CSKY_LR_REGNUM))]
>> +  "TARGET_HARD_FLOAT_ABI && CSKY_ISA_FEATURE (fpv3_hf)"
>> +  "@
>> +    jsr\t%1
>> +    jsr\t%1
>> +    jbsr\t%1"
>> +  [(set_attr "length" "2,4,4")
>> +   (set_attr "type"   "call_jsr,call_jsr,call")]
>> +)
>> +
>> +(define_insn "*call_value_internal_vs"
>> +  [(set (match_operand:SF           0 "register_operand" "=v,v,v")
>> +    (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" 
>> "b, r,S"))
>> +          (match_operand 2 "" "")))
>> +   (clobber (reg:SI CSKY_LR_REGNUM))]
>>     "TARGET_HARD_FLOAT_ABI"
>>     "@
>>       jsr\t%1
>> @@ -3364,9 +3301,9 @@
>>   )
>>     (define_insn "*call_value_internal_vd"
>> -  [(set (match_operand:DF               0 
>> "register_operand"          "=v,v,v")
>> -        (call (mem:SI (match_operand:SI 1 
>> "csky_call_address_operand" "b, r,S"))
>> -              (match_operand 2 "" "")))
>> +  [(set (match_operand:DF           0 "register_operand" "=v,v,v")
>> +    (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" 
>> "b, r,S"))
>> +          (match_operand 2 "" "")))
>>      (clobber (reg:SI CSKY_LR_REGNUM))]
>>     "TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
>>     "@
>> @@ -3378,18 +3315,18 @@
>>   )
>>     (define_insn "*call_value_internal_pic_vs"
>> -  [(set (match_operand:SF               0 "register_operand" "=v")
>> -        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
>> -                      (match_operand    2 "" "")))
>> +  [(set (match_operand:SF           0 "register_operand" "=v")
>> +    (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
>> +              (match_operand    2 "" "")))
>>      (clobber (reg:SI CSKY_LR_REGNUM))]
>>     "flag_pic && TARGET_HARD_FLOAT_ABI"
>>     "* return csky_output_call (operands, 1);"
>>   )
>>     (define_insn "*call_value_internal_pic_vd"
>> -  [(set (match_operand:DF               0 "register_operand" "=v")
>> -        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
>> -                      (match_operand    2 "" "")))
>> +  [(set (match_operand:DF           0 "register_operand" "=v")
>> +    (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
>> +              (match_operand    2 "" "")))
>>      (clobber (reg:SI CSKY_LR_REGNUM))]
>>     "flag_pic && TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
>>     "* return csky_output_call (operands, 1);"
>> diff --git a/gcc/config/csky/csky_cores.def 
>> b/gcc/config/csky/csky_cores.def
>> index 8309e99..fcf42a4 100644
>> --- a/gcc/config/csky/csky_cores.def
>> +++ b/gcc/config/csky/csky_cores.def
>> @@ -38,6 +38,8 @@ CSKY_ARCH ("ck807",  ck807,  CK807,
>>          CSKY_ISA_FEAT (CSKY_ISA_CK807) CSKY_ISA_FEAT (CSKY_ISA_DSP))
>>   CSKY_ARCH ("ck810",  ck810,  CK810,
>>          CSKY_ISA_FEAT (CSKY_ISA_CK810) CSKY_ISA_FEAT (CSKY_ISA_DSP))
>> +CSKY_ARCH ("ck860",  ck860,  CK860,
>> +       CSKY_ISA_FEAT (CSKY_ISA_CK860))
>>   #endif
>>     @@ -181,6 +183,12 @@ CSKY_CORE ("ck810ft",  ck810ff, ck810ft,  
>> CK810,
>>          CSKY_ISA_FEAT_NONE)
>>   CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
>>          CSKY_ISA_FEAT_NONE)
>> +
>> +/* ck860 Architecture Processors */
>> +CSKY_CORE("ck860",    ck860,    ck860,    CK860,
>> +      CSKY_ISA_FEAT_NONE)
>> +CSKY_CORE("ck860f",   ck860f,   ck860f,   CK860,
>> +      CSKY_ISA_FEAT_NONE)
>>   #endif
>>     @@ -196,4 +204,9 @@ CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, 
>> CK810,
>>   CSKY_FPU ("fpv2_sf",   fpv2_sf,      CSKY_ISA_FEAT (CSKY_ISA_FPv2_SF))
>>   CSKY_FPU ("fpv2",      fpv2,      CSKY_ISA_FEAT (CSKY_ISA_FPv2))
>>   CSKY_FPU ("fpv2_divd", fpv2_divd, CSKY_ISA_FEAT (CSKY_ISA_FPv2_DIVD))
>> +
>> +CSKY_FPU ("fpv3_hf",   fpv3_hf,   CSKY_ISA_FEAT (CSKY_ISA_FPv3_HF))
>> +CSKY_FPU ("fpv3_hsf",  fpv3_hsf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_HSF))
>> +CSKY_FPU ("fpv3_sdf",  fpv3_sdf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_SDF))
>> +CSKY_FPU ("fpv3",      fpv3,      CSKY_ISA_FEAT (CSKY_ISA_FPv3))
>>   #endif
>> diff --git a/gcc/config/csky/csky_insn_fpu.md 
>> b/gcc/config/csky/csky_insn_fpu.md
>> index c1e78af..e0d01ab 100644
>> --- a/gcc/config/csky/csky_insn_fpu.md
>> +++ b/gcc/config/csky/csky_insn_fpu.md
>> @@ -18,528 +18,314 @@
>>   ;; along with GCC; see the file COPYING3.  If not see
>>   ;; <http://www.gnu.org/licenses/>.  */
>>   -;; 
>> -------------------------------------------------------------------------
>> -;; Float Abs instructions
>> -;; 
>> -------------------------------------------------------------------------
>> +(define_c_enum "unspec" [
>> +  UNSPEC_FLOOR
>> +  UNSPEC_CEIL
>> +  UNSPEC_BTRUNC
>> +  UNSPEC_RINT
>> +])
>>   -(define_insn "abssf2"
>> -  [(set (match_operand:SF      0 "register_operand" "=v,r")
>> -    (abs:SF (match_operand:SF 1 "register_operand" "v, r")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "@
>> -    fabss\t%0, %1
>> -    bclri\t%0, %1, 31")
>> +(define_c_enum "unspecv" [
>> +  VUNSPEC_GET_FCR     ; Represent fetch of FCR content.
>> +  VUNSPEC_SET_FCR     ; Represent assign of FCR content.
>> +  VUNSPEC_INS_FCR     ; Represent insert of FCR content.
>> +])
>>   -(define_insn "absdf2"
>> -  [(set (match_operand:DF      0 "register_operand" "=v")
>> -    (abs:DF (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fabsd\t%0, %1")
>> +(define_mode_iterator F3ANY [HF SF DF])
>> +(define_mode_attr f3t [(HF "16") (SF "32") (DF "64")])
>>   +(define_mode_iterator SFDF [SF DF])
>> +(define_mode_attr f2t [(SF "32") (DF "64")])
>>   -;; 
>> -------------------------------------------------------------------------
>> -;; Float Neg instructions
>> -;; 
>> -------------------------------------------------------------------------
>> +(define_code_iterator FCMPZ [ne ge lt gt le])
>> +(define_code_attr zero_inst [(ne "nez") (ge "hsz") (lt "ltz") (gt 
>> "hz") (le "lsz")])
>>   -(define_insn "negsf2"
>> -  [(set (match_operand:SF      0 "register_operand" "=v")
>> -    (neg:SF (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fnegs\t%0, %1")
>> +(define_code_iterator FCMP [ne ge lt])
>> +(define_code_attr reg_inst [(ne "ne") (ge "hs") (lt "lt")])
>>   -(define_insn "negdf2"
>> -  [(set (match_operand:DF      0 "register_operand" "=v")
>> -    (neg:DF (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fnegd\t%0, %1")
>> +(define_code_iterator FIX_SU [fix unsigned_fix])
>> +(define_code_attr fixsuop [(fix "")  (unsigned_fix "uns")])
>> +(define_code_attr fixsu   [(fix "s") (unsigned_fix "u")])
>>   +(define_code_iterator FLOAT_SU [float unsigned_float])
>> +(define_code_attr floatsuop [(float "")  (unsigned_float "uns")])
>> +(define_code_attr floatsu   [(float "s") (unsigned_float "u")])
>>   -;; 
>> -------------------------------------------------------------------------
>> -;; Float Sqrt instructions
>> -;; 
>> -------------------------------------------------------------------------
>> +(define_int_iterator FRM  [UNSPEC_FLOOR
>> +               UNSPEC_CEIL UNSPEC_RINT])
>>   -(define_insn "sqrtsf2"
>> -  [(set (match_operand:SF       0 "register_operand" "=v")
>> -    (sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fsqrts\t%0, %1")
>> +(define_int_iterator FRMF [UNSPEC_FLOOR
>> +               UNSPEC_CEIL UNSPEC_BTRUNC])
>>   -(define_insn "sqrtdf2"
>> -  [(set (match_operand:DF       0 "register_operand" "=v")
>> -    (sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
>> - "CSKY_ISA_FEATURE (fpv2_divd)"
>> - "fsqrtd\t%0, %1")
>> +(define_int_attr frm_pattern [(UNSPEC_FLOOR "floor")
>> +                  (UNSPEC_CEIL "ceil")   (UNSPEC_BTRUNC "btrunc")
>> +                  (UNSPEC_RINT "rint")])
>> +
>> +(define_int_attr rm [(UNSPEC_FLOOR ".rni")
>> +             (UNSPEC_CEIL ".rpi")  (UNSPEC_BTRUNC ".rz")
>> +             (UNSPEC_RINT "")])
>>       ;; 
>> -------------------------------------------------------------------------
>> -;; Float Add instructions
>> +;; Float mov instructions
>>   ;; 
>> -------------------------------------------------------------------------
>>   -(define_insn "addsf3"
>> -  [(set (match_operand:SF       0 "register_operand" "=v")
>> -    (plus:SF (match_operand:SF 1 "register_operand" "v")
>> -         (match_operand:SF 2 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fadds\t%0, %1, %2")
>> +(define_expand "movhf"
>> +  [(set (match_operand:HF 0 "general_operand" "")
>> +    (match_operand:HF 1 "general_operand" ""))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "
>> +  {
>> +    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
>> +      {
>> +    operands[1] = force_reg (HFmode, operands[1]);
>> +      }
>> +  }
>> +")
>> +
>> +(define_expand "mov<mode>"
>> +  [(set (match_operand:SFDF 0 "general_operand" "")
>> +    (match_operand:SFDF 1 "general_operand" ""))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>)
>> +   || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "
>> +  {
>> +    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
>> +      {
>> +    operands[1] = force_reg (<MODE>mode, operands[1]);
>> +      }
>> +  }
>> +")
>> +
>> +;; Move float value with general register.
>> +
>> +(define_insn "*e2_movsf"
>> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
>> +       (match_operand:SF 1 "general_operand"      " b,r,m,mF,r"))]
>> +  "CSKY_ISA_FEATURE (E2)
>> +   && !CSKY_ISA_FEATURE (fpv2_sf)
>> +   && !CSKY_ISA_FEATURE (fpv3_sf)"
>> +  "* return csky_output_move (insn, operands, SFmode);"
>> + [(set_attr "length" "2,4,4,4,4")
>> +  (set_attr "type" "alu,alu,load,load,store")]
>> +)
>> +
>> +(define_insn "*e2_movdf"
>> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
>> +       (match_operand:DF 1 "general_operand"      " b,r,m,mF,r"))]
>> +  "CSKY_ISA_FEATURE (E2)
>> +   && !CSKY_ISA_FEATURE (fpv2_df)
>> +   && !CSKY_ISA_FEATURE (fpv3_df)"
>> +  "* return csky_output_movedouble (operands, DFmode);"
>> + [(set_attr "length" "4,8,8,8,8")
>> +  (set_attr "type" "alu,alu,load,load,store")]
>> +)
>>   -(define_insn "adddf3"
>> -  [(set (match_operand:DF       0 "register_operand" "=v")
>> -    (plus:DF (match_operand:DF 1 "register_operand" "v")
>> -         (match_operand:DF 2 "register_operand" "v")))]
>> - "CSKY_ISA_FEATURE (fpv2_df)"
>> - "faddd\t%0, %1, %2")
>> +(define_insn "*e1_movsf"
>> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
>> +    (match_operand:SF 1 "general_operand"      " r,m,mF,r"))]
>> +  "CSKY_ISA_FEATURE (E1)"
>> +  "* return csky_output_ck801_move (insn, operands, SFmode);"
>> +  [(set_attr "length" "2,4,4,4")
>> +   (set_attr "type" "alu,load,load,store")]
>> +)
>>   +(define_insn "*e1_movdf"
>> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
>> +    (match_operand:DF 1 "general_operand"      " r,m,mF,r"))]
>> +  "CSKY_ISA_FEATURE (E1)"
>> +  "* return csky_output_ck801_movedouble (operands, DFmode);"
>> +  [(set_attr "length" "4,8,8,8")
>> +   (set_attr "type" "alu,load,load,store")]
>> +)
>>     ;; 
>> -------------------------------------------------------------------------
>> -;; Float Sub instructions
>> +;; Float Mul instructions
>>   ;; 
>> -------------------------------------------------------------------------
>>   -(define_insn "subsf3"
>> -  [(set (match_operand:SF        0 "register_operand" "=v")
>> -    (minus:SF (match_operand:SF 1 "register_operand" "v")
>> -          (match_operand:SF 2 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fsubs\t%0, %1, %2")
>> +(define_expand "mulhf3"
>> +  [(set (match_operand:HF        0 "register_operand" "=v")
>> +    (mult:HF (match_operand:HF   1 "register_operand" "v")
>> +         (match_operand:HF   2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "")
>>   -(define_insn "subdf3"
>> -  [(set (match_operand:DF        0 "register_operand" "=v")
>> -    (minus:DF (match_operand:DF 1 "register_operand" "v")
>> -          (match_operand:DF 2 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fsubd\t%0, %1, %2")
>> +(define_expand "mul<mode>3"
>> +  [(set (match_operand:SFDF        0 "register_operand" "=v")
>> +    (mult:SFDF (match_operand:SFDF   1 "register_operand" "v")
>> +         (match_operand:SFDF   2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>)
>> +  || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "")
>>   +(define_expand "fma<mode>4"
>> +  [(set (match_operand:F3ANY        0 "register_operand" "=v")
>> +    (fma:F3ANY (match_operand:F3ANY  1 "register_operand" "v")
>> +           (match_operand:F3ANY  2 "register_operand" "v")
>> +           (match_operand:F3ANY  3 "register_operand" "0")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "")
>>     ;; 
>> -------------------------------------------------------------------------
>> -;; Float Mul instructions
>> +;; Float ADD SUB NEG ABS instructions
>>   ;; 
>> -------------------------------------------------------------------------
>>   -(define_insn "mulsf3"
>> -  [(set (match_operand:SF       0 "register_operand" "=v")
>> -    (mult:SF (match_operand:SF 1 "register_operand" "v")
>> -         (match_operand:SF 2 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fmuls\t%0, %1, %2")
>> -
>> -(define_insn "muldf3"
>> -  [(set (match_operand:DF       0 "register_operand" "=v")
>> -    (mult:DF (match_operand:DF 1 "register_operand" "v")
>> -         (match_operand:DF 2 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fmuld\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_nmulsf3_1"
>> -  [(set (match_operand:SF           0 "register_operand" "=v")
>> -    (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
>> -         (match_operand:SF       2 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
>> -  "fnmuls\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_nmulsf3_2"
>> -  [(set (match_operand:SF           0 "register_operand" "=v")
>> -    (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
>> -             (match_operand:SF 2 "register_operand" "v"))))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fnmuls\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_nmuldf3_1"
>> -  [(set (match_operand:DF           0 "register_operand" "=v")
>> -    (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
>> -         (match_operand:DF       2 "register_operand" "v")))]
>> - "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
>> - "fnmuld\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_nmuldf3_2"
>> -  [(set (match_operand:DF           0 "register_operand" "=v")
>> -    (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
>> -             (match_operand:DF 2 "register_operand" "v"))))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fnmuld\t%0, %1, %2")
>> +(define_expand "addhf3"
>> +  [(set (match_operand:HF       0 "register_operand" "")
>> +    (plus:HF (match_operand:HF  1 "register_operand" "")
>> +         (match_operand:HF  2 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  ""
>> +)
>> +
>> +(define_expand "add<mode>3"
>> +  [(set (match_operand:SFDF         0 "register_operand" "")
>> +    (plus:SFDF (match_operand:SFDF  1 "register_operand" "")
>> +           (match_operand:SFDF  2 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  ""
>> +)
>>   +(define_expand "subhf3"
>> +  [(set (match_operand:HF        0 "register_operand" "")
>> +    (minus:HF (match_operand:HF  1 "register_operand" "")
>> +          (match_operand:HF  2 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  ""
>> +)
>>   -;; 
>> -------------------------------------------------------------------------
>> -;; Float Div instructions
>> -;; 
>> -------------------------------------------------------------------------
>> +(define_expand "sub<mode>3"
>> +  [(set (match_operand:SFDF          0 "register_operand" "")
>> +    (minus:SFDF (match_operand:SFDF  1 "register_operand" "")
>> +            (match_operand:SFDF  2 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  ""
>> +)
>>   -(define_expand "divsf3"
>> -  [(set (match_operand:SF      0 "register_operand" "")
>> -    (div:SF (match_operand:SF 1 "csky_arith_float1_operand" "")
>> -        (match_operand:SF 2 "register_operand" "")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "")
>> +(define_expand "abshf2"
>> +  [(set (match_operand:HF       0 "register_operand" "")
>> +    (abs:HF (match_operand:HF   1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  ""
>> +)
>>   -(define_insn "*fpuv2_divsf3"
>> -  [(set (match_operand:SF      0 "register_operand" "=v")
>> -    (div:SF (match_operand:SF 1 "register_operand" "v")
>> -        (match_operand:SF 2 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fdivs\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_1_divsf3"
>> -  [(set (match_operand:SF      0 "register_operand" "=v")
>> -    (div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
>> -        (match_operand:SF 2 "register_operand"        "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "frecips\t%0, %2")
>> -
>> -
>> -(define_expand "divdf3"
>> -  [(set (match_operand:DF 0 "register_operand" "")
>> -    (div:DF (match_operand:DF 1 "csky_arith_float1_operand" "")
>> -        (match_operand:DF 2 "register_operand" "")))]
>> -  "CSKY_ISA_FEATURE (fpv2_divd)"
>> -  "")
>> +(define_expand "abs<mode>2"
>> +  [(set (match_operand:SFDF         0 "register_operand" "")
>> +    (abs:SFDF (match_operand:SFDF   1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  ""
>> +)
>>   -(define_insn "*fpuv2_divdf3"
>> -  [(set (match_operand:DF      0 "register_operand" "=v")
>> -    (div:DF (match_operand:DF 1 "register_operand" "v")
>> -        (match_operand:DF 2 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_divd)"
>> -  "fdivd\t%0, %1, %2")
>> +(define_expand "neghf2"
>> +  [(set (match_operand:HF       0 "register_operand" "")
>> +    (neg:HF (match_operand:HF   1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  ""
>> +)
>>   -(define_insn "*fpuv2_1_divdf3"
>> -  [(set (match_operand:DF      0 "register_operand" "=v")
>> -    (div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
>> -        (match_operand:DF 2 "register_operand"        "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_divd)"
>> -  "frecipd\t%0, %2")
>> +(define_expand "neg<mode>2"
>> +  [(set (match_operand:SFDF       0 "register_operand" "")
>> +    (neg:SFDF (match_operand:SFDF 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  ""
>> +)
>>   +(define_expand "sqrthf2"
>> +  [(set (match_operand:HF       0 "register_operand" "")
>> +    (sqrt:HF (match_operand:HF  1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  ""
>> +)
>> +
>> +(define_expand "sqrt<mode>2"
>> +  [(set (match_operand:SFDF        0 "register_operand" "")
>> +    (sqrt:SFDF (match_operand:SFDF 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  ""
>> +)
>>     ;; 
>> -------------------------------------------------------------------------
>> -;; Float add(sub) with mult instructions
>> +;; Float div instructions
>>   ;; 
>> -------------------------------------------------------------------------
>>   -;; vrz <= vrz + vrx * vry
>> -(define_insn "*fpuv2_fmacs"
>> -  [(set (match_operand:SF            0 "register_operand" "=v")
>> -    (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
>> -              (match_operand:SF 2 "register_operand" "v"))
>> -         (match_operand:SF        3 "register_operand" "0")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fmacs\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_fmacd"
>> -  [(set (match_operand:DF            0 "register_operand" "=v")
>> -    (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
>> -              (match_operand:DF 2 "register_operand" "v"))
>> -         (match_operand:DF        3 "register_operand" "0")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fmacd\t%0, %1, %2")
>> -
>> -;; vrz <= vrz - vrx * vry
>> -(define_insn "*fpuv2_fnmacs"
>> -  [(set (match_operand:SF             0 "register_operand" "=v")
>> -    (minus:SF (match_operand:SF         1 "register_operand" "0")
>> -          (mult:SF (match_operand:SF 2 "register_operand" "v")
>> -               (match_operand:SF 3 "register_operand" "v"))))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fnmacs\t%0, %2, %3")
>> -
>> -(define_insn "*fpuv2_fnmacd"
>> -  [(set (match_operand:DF             0 "register_operand" "=v")
>> -    (minus:DF (match_operand:DF         1 "register_operand" "0")
>> -          (mult:DF (match_operand:DF 2 "register_operand" "v")
>> -               (match_operand:DF 3 "register_operand" "v"))))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fnmacd\t%0, %2, %3")
>> -
>> -;; vrz <= vrx * vry - vrz
>> -(define_insn "*fpuv2_fmscs"
>> -  [(set (match_operand:SF             0 "register_operand" "=v")
>> -    (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
>> -               (match_operand:SF 2 "register_operand" "v"))
>> -          (match_operand:SF         3 "register_operand" "0")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fmscs\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_fmscd"
>> -  [(set (match_operand:DF 0 "register_operand" "=v")
>> -    (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
>> -               (match_operand:DF 2 "register_operand" "v"))
>> -          (match_operand:DF 3 "register_operand" "0")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fmscd\t%0, %1, %2")
>> -
>> -;; vrz = - (vrz + vrx * vry)
>> -(define_insn "*fpuv2_fnmscs_1"
>> -  [(set (match_operand:SF                 0 "register_operand" "=v")
>> -    (minus:SF (mult:SF (neg:SF (match_operand:SF 1 
>> "register_operand" "%v"))
>> -               (match_operand:SF         2 "register_operand" "v"))
>> -          (match_operand:SF             3 "register_operand" "0")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fnmscs\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_fnmscs_2"
>> -  [(set (match_operand:SF                0 "register_operand" "=v")
>> -    (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" 
>> "v")
>> -                  (match_operand:SF 2 "register_operand" "v"))
>> -             (match_operand:SF        3 "register_operand" "0"))))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fnmscs\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_fnmscd_1"
>> -  [(set (match_operand:DF 0 "register_operand" "=v")
>> -    (minus:DF (mult:DF (neg:DF (match_operand:DF 1 
>> "register_operand" "%v"))
>> -               (match_operand:DF 2 "register_operand" "v"))
>> -          (match_operand:DF 3 "register_operand" "0")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fnmscd\t%0, %1, %2")
>> -
>> -(define_insn "*fpuv2_fnmscd_2"
>> -  [(set (match_operand:DF 0 "register_operand" "=v")
>> -    (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" 
>> "v")
>> -                  (match_operand:DF 2 "register_operand" "v"))
>> -             (match_operand:DF 3 "register_operand" "0"))))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fnmscd\t%0, %1, %2")
>> +(define_expand "div<mode>3"
>> +  [(set (match_operand:SFDF       0 "register_operand" "")
>> +    (div:SFDF (match_operand:SFDF 1 "csky_arith_float1_operand" "")
>> +          (match_operand:SFDF 2 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "")
>>   +(define_expand "divhf3"
>> + [(set (match_operand:HF 0 "register_operand" "")
>> +       (div:HF (match_operand:HF 1 "csky_arith_float1_operand" "")
>> +           (match_operand:HF 2 "register_operand" "")))]
>> + "CSKY_ISA_FEATURE(fpv3_hf)"
>> + "")
>>     ;; 
>> -------------------------------------------------------------------------
>>   ;; Float compare instructions
>>   ;; 
>> -------------------------------------------------------------------------
>>   -(define_expand "cbranchsf4"
>> +(define_expand "cbranch<mode>4"
>>     [(set (pc) (if_then_else (match_operator 0 
>> "csky_float_comparison_operator"
>> -                 [(match_operand:SF 1 "register_operand")
>> -                  (match_operand:SF 2 "csky_compare_operand_float")])
>> +                [(match_operand:SFDF 1 "register_operand")
>> +                 (match_operand:SFDF 2 "csky_compare_operand_float")])
>>                  (label_ref (match_operand 3 ""))
>>                  (pc)))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "
>> -  {
>> -    enum rtx_code code = GET_CODE (operands[0]);
>> -    bool invert = csky_emit_compare_float (code, operands[1], 
>> operands[2]);
>> +"CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +"{
>> +  enum rtx_code code = GET_CODE (operands[0]);
>> +  bool invert;
>>   -    if (invert)
>> -      emit_jump_insn (gen_csky_jbf (operands[3]));
>> -    else
>> -      emit_jump_insn (gen_csky_jbt (operands[3]));
>> +  invert = csky_emit_compare_float (code, operands[1], operands[2]);
>>   -    DONE;
>> -  }")
>> -
>> -(define_insn "*fpuv2_unordered"
>> -  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 
>> "register_operand" "v")
>> -                  (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fcmpuos\t%0, %1")
>> -
>> -(define_insn "*fpuv2_unordered_zero"
>> -  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 
>> "register_operand" "v")
>> -                  (match_operand:SF 1 "csky_const_float0_operand" 
>> "i")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fcmpuos\t%0, %0")
>> -
>> -(define_insn "*fpuv2_ne"
>> -  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
>> -               (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fcmpnes\t%0, %1")
>> -
>> -(define_insn "*fpuv2_gt"
>> -  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
>> -               (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fcmplts\t%1, %0")
>> -
>> -(define_insn "*fpuv2_ge"
>> -  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
>> -               (match_operand:SF 1 "register_operand" "v")))]
>> - "CSKY_ISA_FEATURE (fpv2_sf)"
>> - "fcmphss\t%0, %1")
>> -
>> -(define_insn "*fpuv2_lt"
>> -  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
>> -               (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fcmplts\t%0, %1")
>> -
>> -(define_insn "*fpuv2_le"
>> -  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
>> -               (match_operand:SF 1 "register_operand" "v")))]
>> - "CSKY_ISA_FEATURE (fpv2_sf)"
>> - "fcmphss\t%1, %0")
>> -
>> -(define_insn "*fpuv2_gez"
>> -  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 
>> "register_operand"       "v")
>> -               (match_operand:SF 1 "csky_const_float0_operand" "i")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fcmpzhss\t%0")
>> -
>> -(define_insn "*fpuv2_nez"
>> -  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 
>> "register_operand"       "v")
>> -               (match_operand:SF 1 "csky_const_float0_operand" "i")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fcmpznes\t%0")
>> -
>> -
>> -(define_expand "cbranchdf4"
>> -  [(set (pc) (if_then_else (match_operator 0 
>> "csky_float_comparison_operator"
>> -                 [(match_operand:DF 1 "register_operand")
>> -                  (match_operand:DF 2 "csky_compare_operand_float")])
>> -               (label_ref (match_operand 3 ""))
>> -               (pc)))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "
>> -  {
>> -    enum rtx_code code = GET_CODE (operands[0]);
>> -    bool invert = csky_emit_compare_float (code, operands[1], 
>> operands[2]);
>> +  if (invert)
>> +    emit_jump_insn (gen_csky_jbf (operands[3]));
>> +  else
>> +    emit_jump_insn (gen_csky_jbt (operands[3]));
>>   -    if (invert)
>> -      emit_jump_insn (gen_csky_jbf (operands[3]));
>> -    else
>> -      emit_jump_insn (gen_csky_jbt (operands[3]));
>> +  DONE;
>>   -    DONE;
>>   }")
>>   -(define_insn "*fpuv2_dunordered"
>> -  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 
>> "register_operand" "v")
>> -                  (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fcmpuod\t%0, %1")
>> -
>> -(define_insn "*fpuv2_dunordered_zero"
>> -  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 
>> "register_operand" "v")
>> -                  (match_operand:DF 1 "csky_const_float0_operand" 
>> "i")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fcmpuod\t%0, %0")
>> -
>> -(define_insn "*fpuv2_dne"
>> -  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
>> -               (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fcmpned\t%0, %1")
>> -
>> -(define_insn "*fpuv2_dgt"
>> -  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
>> -               (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fcmpltd\t%1, %0")
>> -
>> -(define_insn "*fpuv2_dge"
>> -  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
>> -               (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fcmphsd\t%0, %1")
>> -
>> -(define_insn "*fpuv2_dlt"
>> -  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
>> -               (match_operand:DF 1 "register_operand" "v")))]
>> - "CSKY_ISA_FEATURE (fpv2_df)"
>> - "fcmpltd\t%0, %1")
>> -
>> -(define_insn "*fpuv2_dle"
>> -  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
>> -               (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fcmphsd\t%1, %0")
>> -
>> -(define_insn "*fpuv2_dgez"
>> -  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 
>> "register_operand"       "v")
>> -               (match_operand:DF 1 "csky_const_float0_operand" "i")))]
>> - "CSKY_ISA_FEATURE (fpv2_df)"
>> - "fcmpzhsd\t%0")
>> -
>> -(define_insn "*fpuv2_dnez"
>> -  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 
>> "register_operand"       "v")
>> -               (match_operand:DF 1 "csky_const_float0_operand" "i")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fcmpzned\t%0")
>> +(define_expand "cbranchhf4"
>> +  [(set (pc) (if_then_else (match_operator 0 
>> "csky_float_comparison_operator"
>> +                [(match_operand:HF 1 "register_operand")
>> +                 (match_operand:HF 2 "csky_compare_operand_float")])
>> +               (label_ref (match_operand 3 ""))
>> +               (pc)))]
>> +"CSKY_ISA_FEATURE(fpv3_hf)"
>> +"{
>> +  enum rtx_code code = GET_CODE (operands[0]);
>> +  bool invert;
>>   +  invert = csky_emit_compare_float (code, operands[1], operands[2]);
>>   -;; 
>> -------------------------------------------------------------------------
>> -;; Float convert instructions
>> -;; 
>> -------------------------------------------------------------------------
>> +  if (invert)
>> +    emit_jump_insn (gen_csky_jbf (operands[3]));
>> +  else
>> +    emit_jump_insn (gen_csky_jbt (operands[3]));
>>   -;; DF <- SF
>> -(define_insn "extendsfdf2"
>> -  [(set (match_operand:DF           0 "register_operand" "=v")
>> -    (float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fstod\t%0, %1")
>> -
>> -;; SF <- DF
>> -(define_insn "truncdfsf2"
>> -  [(set (match_operand:SF             0 "register_operand" "=v")
>> -    (float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fdtos\t%0, %1")
>> -
>> -;; SF <- SI
>> -(define_insn "floatsisf2"
>> -  [(set (match_operand:SF        0 "register_operand" "=v")
>> -    (float:SF (match_operand:SI 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fsitos\t%0, %1")
>> -
>> -;; DF <- SI
>> -(define_insn "floatsidf2"
>> -  [(set (match_operand:DF        0 "register_operand" "=v")
>> -    (float:DF (match_operand:SI 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fsitod\t%0, %1")
>> -
>> -;; SF <- unsigned SI
>> -(define_insn "floatunssisf2"
>> -  [(set (match_operand:SF             0 "register_operand" "=v")
>> -    (unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fuitos\t%0, %1")
>> -
>> -;; DF <- unsigned SI
>> -(define_insn "floatunssidf2"
>> -  [(set (match_operand:DF             0 "register_operand" "=v")
>> -    (unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fuitod\t%0, %1")
>> -
>> -;; SI <- SF
>> -(define_insn "fix_truncsfsi2"
>> -  [(set (match_operand:SI      0 "register_operand" "=v")
>> -    (fix:SI (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fstosi.rz\t%0, %1")
>> -
>> -;; SI <- DF
>> -(define_insn "fix_truncdfsi2"
>> -  [(set (match_operand:SI      0 "register_operand" "=v")
>> -    (fix:SI (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fdtosi.rz\t%0, %1")
>> -
>> -;; unsigned SI <- SF
>> -(define_insn "fixuns_truncsfsi2"
>> -  [(set (match_operand:SI           0 "register_operand" "=v")
>> -    (unsigned_fix:SI (match_operand:SF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "fstoui.rz\t%0, %1")
>> -
>> -;; unsigned SI <- DF
>> -(define_insn "fixuns_truncdfsi2"
>> -  [(set (match_operand:SI           0 "register_operand" "=v")
>> -    (unsigned_fix:SI (match_operand:DF 1 "register_operand" "v")))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "fdtoui.rz\t%0, %1")
>> +  DONE;
>>   +}")
>>     ;; 
>> -------------------------------------------------------------------------
>> -;; Float mov instructions
>> +;; Instructions for float cstore
>>   ;; 
>> -------------------------------------------------------------------------
>>   -;; Note:  movsf and movdf patterns are in csky.md.
>> -
>> -;; cstore SF
>> -(define_expand "cstoresf4"
>> +(define_expand "cstore<mode>4"
>>     [(set (match_operand:SI 0 "register_operand" "")
>> -    (match_operator      1 "ordered_comparison_operator"
>> -      [(match_operand:SF 2 "register_operand" "")
>> -       (match_operand:SF 3 "csky_compare_operand_float" "")]))]
>> -  "CSKY_ISA_FEATURE (fpv2_sf)"
>> -  "
>> -  {
>> -    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
>> -                       operands[2], operands[3]);
>> -    if (invert)
>> +    (match_operator   1 "csky_float_comparison_operator"
>> +      [(match_operand:SFDF 2 "register_operand" "")
>> +       (match_operand:SFDF 3 "csky_compare_operand_float" "")]))]
>> +  "CSKY_ISA_FEATURE (fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "{
>> +    bool invert;
>> +
>> +    invert = csky_emit_compare_float (GET_CODE (operands[1]),
>> +                 operands[2], operands[3]);
>> +    if(invert)
>>         emit_insn (gen_mvcv (operands[0]));
>>       else
>>         emit_insn (gen_mvc (operands[0]));
>> @@ -547,21 +333,91 @@
>>     }"
>>   )
>>   -;; cstore DF
>> -(define_expand "cstoredf4"
>> +(define_expand "cstorehf4"
>>     [(set (match_operand:SI 0 "register_operand" "")
>> -    (match_operator 1 "ordered_comparison_operator"
>> -      [(match_operand:DF 2 "register_operand" "")
>> -       (match_operand:DF 3 "csky_compare_operand_float" "")]))]
>> -  "CSKY_ISA_FEATURE (fpv2_df)"
>> -  "
>> -  {
>> -    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
>> -                       operands[2], operands[3]);
>> -    if (invert)
>> +    (match_operator   1 "csky_float_comparison_operator"
>> +      [(match_operand:HF 2 "register_operand" "")
>> +       (match_operand:HF 3 "csky_compare_operand_float" "")]))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "{
>> +    bool invert;
>> +
>> +    invert = csky_emit_compare_float (GET_CODE (operands[1]),
>> +                 operands[2], operands[3]);
>> +    if(invert)
>>         emit_insn (gen_mvcv (operands[0]));
>>       else
>>         emit_insn (gen_mvc (operands[0]));
>>       DONE;
>>     }"
>>   )
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float convert instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +;; SF <- HF
>> +(define_expand "extendhfsf2"
>> +  [(set (match_operand:SF          0 "register_operand" "")
>> +    (float_extend:SF (match_operand:HF 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "")
>> +
>> +;; HF <- SF
>> +(define_expand "truncsfhf2"
>> +  [(set (match_operand:HF             0 "register_operand" "")
>> +    (float_truncate:HF (match_operand:SF 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "")
>> +
>> +;; DF <- SF
>> +(define_expand "extendsfdf2"
>> +  [(set (match_operand:DF          0 "register_operand" "")
>> +    (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
>> +  "")
>> +
>> +;; SF <- DF
>> +(define_expand "truncdfsf2"
>> +  [(set (match_operand:SF            0 "register_operand" "")
>> +    (float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
>> +  "")
>> +
>> +;; HF <- unsigned SI,SI
>> +(define_expand "float<floatsuop>sihf2"
>> +  [(set (match_operand:HF       0 "register_operand" "")
>> +    (FLOAT_SU:HF (match_operand:SI 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "")
>> +
>> +;; DF,SF <- unsigned SI,SI
>> +(define_expand "float<floatsuop>si<mode>2"
>> +  [(set (match_operand:SFDF            0 "register_operand" "")
>> +    (FLOAT_SU:SFDF (match_operand:SI 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "")
>> +
>> +;; HF <- unsigned HI,HI
>> +(define_expand "float<floatsuop>hihf2"
>> +  [(set (match_operand:HF       0 "register_operand" "")
>> +    (FLOAT_SU:HF (match_operand:HI 1 "register_operand" "")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "")
>> +
>> +;; unsigned SI,SI <- HF
>> +(define_expand "fix<fixsuop>_trunchfsi2"
>> +  [(set (match_operand:SI        0 "register_operand" "")
>> +    (FIX_SU:SI (fix:HF (match_operand:HF 1 "register_operand" ""))))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "")
>> +
>> +;; unsigned SI,SI <- DF,SF
>> +(define_expand "fix<fixsuop>_trunc<mode>si2"
>> +  [(set (match_operand:SI        0 "register_operand" "")
>> +    (FIX_SU:SI (fix:SFDF (match_operand:SFDF 1 "register_operand" 
>> ""))))]
>> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "")
>> +
>> +(include "csky_insn_fpuv3.md")
>> +(include "csky_insn_fpuv2.md")
>> diff --git a/gcc/config/csky/csky_insn_fpuv2.md 
>> b/gcc/config/csky/csky_insn_fpuv2.md
>> new file mode 100644
>> index 0000000..0a680f8
>> --- /dev/null
>> +++ b/gcc/config/csky/csky_insn_fpuv2.md
>> @@ -0,0 +1,470 @@
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Abs instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpuv2_abssf2"
>> +  [(set (match_operand:SF     0 "register_operand" "=v,a,r")
>> +    (abs:SF (match_operand:SF 1 "register_operand" "v, 0,r")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "@
>> +    fabss\t%0, %1
>> +    bclri\t%0, %1, 31
>> +    bclri\t%0, %1, 31"
>> +  [(set_attr "length" "4,2,4")])
>> +
>> +(define_insn "*fpuv2_absdf2"
>> +  [(set (match_operand:DF     0 "register_operand" "=v")
>> +    (abs:DF (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fabsd\t%0, %1")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Neg instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpuv2_negsf2"
>> +  [(set (match_operand:SF     0 "register_operand" "=v")
>> +    (neg:SF (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fnegs\t%0, %1")
>> +
>> +(define_insn "*fpuv2_negdf2"
>> +  [(set (match_operand:DF     0 "register_operand" "=v")
>> +    (neg:DF (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fnegd\t%0, %1")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Sqrt instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpuv2_sqrtsf2"
>> +  [(set (match_operand:SF      0 "register_operand" "=v")
>> +    (sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fsqrts\t%0, %1")
>> +
>> +(define_insn "*fpuv2_sqrtdf2"
>> +  [(set (match_operand:DF      0 "register_operand" "=v")
>> +    (sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
>> + "CSKY_ISA_FEATURE (fpv2_divd)"
>> + "fsqrtd\t%0, %1")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Add instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpuv2_addsf3"
>> +  [(set (match_operand:SF      0 "register_operand" "=v")
>> +    (plus:SF (match_operand:SF 1 "register_operand" "v")
>> +         (match_operand:SF 2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fadds\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_adddf3"
>> +  [(set (match_operand:DF      0 "register_operand" "=v")
>> +    (plus:DF (match_operand:DF 1 "register_operand" "v")
>> +         (match_operand:DF 2 "register_operand" "v")))]
>> + "CSKY_ISA_FEATURE (fpv2_df)"
>> + "faddd\t%0, %1, %2")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Sub instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpuv2_subsf3"
>> +  [(set (match_operand:SF       0 "register_operand" "=v")
>> +    (minus:SF (match_operand:SF 1 "register_operand" "v")
>> +          (match_operand:SF 2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fsubs\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_subdf3"
>> +  [(set (match_operand:DF       0 "register_operand" "=v")
>> +    (minus:DF (match_operand:DF 1 "register_operand" "v")
>> +          (match_operand:DF 2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fsubd\t%0, %1, %2")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Mul instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv2_mulsf3"
>> +  [(set (match_operand:SF      0 "register_operand" "=v")
>> +    (mult:SF (match_operand:SF 1 "register_operand" "v")
>> +         (match_operand:SF 2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fmuls\t%0, %1, %2")
>> +
>> +(define_insn "*fpv2_muldf3"
>> +  [(set (match_operand:DF      0 "register_operand" "=v")
>> +    (mult:DF (match_operand:DF 1 "register_operand" "v")
>> +         (match_operand:DF 2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fmuld\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_nmulsf3_1"
>> +  [(set (match_operand:SF          0 "register_operand" "=v")
>> +    (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
>> +         (match_operand:SF     2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
>> +  "fnmuls\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_nmulsf3_2"
>> +  [(set (match_operand:SF          0 "register_operand" "=v")
>> +    (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
>> +             (match_operand:SF 2 "register_operand" "v"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fnmuls\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_nmuldf3_1"
>> +  [(set (match_operand:DF          0 "register_operand" "=v")
>> +    (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
>> +         (match_operand:DF     2 "register_operand" "v")))]
>> + "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
>> + "fnmuld\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_nmuldf3_2"
>> +  [(set (match_operand:DF          0 "register_operand" "=v")
>> +    (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
>> +             (match_operand:DF 2 "register_operand" "v"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fnmuld\t%0, %1, %2")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Div instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpuv2_divsf3"
>> +  [(set (match_operand:SF     0 "register_operand" "=v")
>> +    (div:SF (match_operand:SF 1 "register_operand" "v")
>> +        (match_operand:SF 2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fdivs\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_1_divsf3"
>> +  [(set (match_operand:SF     0 "register_operand"      "=v")
>> +    (div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
>> +        (match_operand:SF 2 "register_operand"      "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "frecips\t%0, %2")
>> +
>> +(define_insn "*fpuv2_divdf3"
>> +  [(set (match_operand:DF     0 "register_operand" "=v")
>> +    (div:DF (match_operand:DF 1 "register_operand" "v")
>> +        (match_operand:DF 2 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_divd)"
>> +  "fdivd\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_1_divdf3"
>> +  [(set (match_operand:DF     0 "register_operand"      "=v")
>> +    (div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
>> +        (match_operand:DF 2 "register_operand"      "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_divd)"
>> +  "frecipd\t%0, %2")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float add(sub) with mult instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +;; vrz <= vrz + vrx * vry
>> +(define_insn "*fpuv2_fmacs"
>> +  [(set (match_operand:SF           0 "register_operand" "=v")
>> +    (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
>> +              (match_operand:SF 2 "register_operand" "v"))
>> +         (match_operand:SF      3 "register_operand" "0")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fmacs\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_fmacd"
>> +  [(set (match_operand:DF           0 "register_operand" "=v")
>> +    (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
>> +              (match_operand:DF 2 "register_operand" "v"))
>> +         (match_operand:DF      3 "register_operand" "0")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fmacd\t%0, %1, %2")
>> +
>> +;; vrz <= vrz - vrx * vry
>> +(define_insn "*fpuv2_fnmacs"
>> +  [(set (match_operand:SF            0 "register_operand" "=v")
>> +    (minus:SF (match_operand:SF      1 "register_operand" "0")
>> +          (mult:SF (match_operand:SF 2 "register_operand" "v")
>> +               (match_operand:SF 3 "register_operand" "v"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fnmacs\t%0, %2, %3")
>> +
>> +(define_insn "*fpuv2_fnmacd"
>> +  [(set (match_operand:DF            0 "register_operand" "=v")
>> +    (minus:DF (match_operand:DF      1 "register_operand" "0")
>> +          (mult:DF (match_operand:DF 2 "register_operand" "v")
>> +               (match_operand:DF 3 "register_operand" "v"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fnmacd\t%0, %2, %3")
>> +
>> +;; vrz <= vrx * vry - vrz
>> +(define_insn "*fpuv2_fmscs"
>> +  [(set (match_operand:SF            0 "register_operand" "=v")
>> +    (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
>> +               (match_operand:SF 2 "register_operand" "v"))
>> +          (match_operand:SF      3 "register_operand" "0")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fmscs\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_fmscd"
>> +  [(set (match_operand:DF 0 "register_operand" "=v")
>> +    (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
>> +               (match_operand:DF 2 "register_operand" "v"))
>> +          (match_operand:DF 3 "register_operand" "0")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fmscd\t%0, %1, %2")
>> +
>> +;; vrz = - (vrz + vrx * vry)
>> +(define_insn "*fpuv2_fnmscs_1"
>> +  [(set (match_operand:SF                0 "register_operand" "=v")
>> +    (minus:SF (mult:SF (neg:SF (match_operand:SF 1 
>> "register_operand" "%v"))
>> +               (match_operand:SF     2 "register_operand" "v"))
>> +          (match_operand:SF          3 "register_operand" "0")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fnmscs\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_fnmscs_2"
>> +  [(set (match_operand:SF               0 "register_operand" "=v")
>> +    (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" 
>> "v")
>> +                  (match_operand:SF 2 "register_operand" "v"))
>> +             (match_operand:SF      3 "register_operand" "0"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fnmscs\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_fnmscd_1"
>> +  [(set (match_operand:DF 0 "register_operand" "=v")
>> +    (minus:DF (mult:DF (neg:DF (match_operand:DF 1 
>> "register_operand" "%v"))
>> +               (match_operand:DF 2 "register_operand" "v"))
>> +          (match_operand:DF 3 "register_operand" "0")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fnmscd\t%0, %1, %2")
>> +
>> +(define_insn "*fpuv2_fnmscd_2"
>> +  [(set (match_operand:DF 0 "register_operand" "=v")
>> +    (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" 
>> "v")
>> +                  (match_operand:DF 2 "register_operand" "v"))
>> +             (match_operand:DF 3 "register_operand" "0"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fnmscd\t%0, %1, %2")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float compare instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpuv2_unordered"
>> +  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 
>> "register_operand" "v")
>> +                  (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fcmpuos\t%0, %1")
>> +
>> +(define_insn "*fpuv2_unordered_zero"
>> +  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 
>> "register_operand" "v")
>> +                  (match_operand:SF 1 "csky_const_float0_operand" 
>> "i")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fcmpuos\t%0, %0")
>> +
>> +(define_insn "*fpuv2_ne"
>> +  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
>> +               (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fcmpnes\t%0, %1")
>> +
>> +(define_insn "*fpuv2_gt"
>> +  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
>> +               (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fcmplts\t%1, %0")
>> +
>> +(define_insn "*fpuv2_ge"
>> +  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
>> +               (match_operand:SF 1 "register_operand" "v")))]
>> + "CSKY_ISA_FEATURE (fpv2_sf)"
>> + "fcmphss\t%0, %1")
>> +
>> +(define_insn "*fpuv2_lt"
>> +  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
>> +               (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fcmplts\t%0, %1")
>> +
>> +(define_insn "*fpuv2_le"
>> +  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
>> +               (match_operand:SF 1 "register_operand" "v")))]
>> + "CSKY_ISA_FEATURE (fpv2_sf)"
>> + "fcmphss\t%1, %0")
>> +
>> +(define_insn "*fpuv2_gez"
>> +  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 
>> "register_operand"      "v")
>> +               (match_operand:SF 1 "csky_const_float0_operand" "i")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fcmpzhss\t%0")
>> +
>> +(define_insn "*fpuv2_nez"
>> +  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 
>> "register_operand"      "v")
>> +               (match_operand:SF 1 "csky_const_float0_operand" "i")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fcmpznes\t%0")
>> +
>> +(define_insn "*fpuv2_dunordered"
>> +  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 
>> "register_operand" "v")
>> +                  (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fcmpuod\t%0, %1")
>> +
>> +(define_insn "*fpuv2_dunordered_zero"
>> +  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 
>> "register_operand" "v")
>> +                  (match_operand:DF 1 "csky_const_float0_operand" 
>> "i")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fcmpuod\t%0, %0")
>> +
>> +(define_insn "*fpuv2_dne"
>> +  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
>> +               (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fcmpned\t%0, %1")
>> +
>> +(define_insn "*fpuv2_dgt"
>> +  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
>> +               (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fcmpltd\t%1, %0")
>> +
>> +(define_insn "*fpuv2_dge"
>> +  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
>> +               (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fcmphsd\t%0, %1")
>> +
>> +(define_insn "*fpuv2_dlt"
>> +  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
>> +               (match_operand:DF 1 "register_operand" "v")))]
>> + "CSKY_ISA_FEATURE (fpv2_df)"
>> + "fcmpltd\t%0, %1")
>> +
>> +(define_insn "*fpuv2_dle"
>> +  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
>> +               (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fcmphsd\t%1, %0")
>> +
>> +(define_insn "*fpuv2_dgez"
>> +  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 
>> "register_operand"      "v")
>> +               (match_operand:DF 1 "csky_const_float0_operand" "i")))]
>> + "CSKY_ISA_FEATURE (fpv2_df)"
>> + "fcmpzhsd\t%0")
>> +
>> +(define_insn "*fpuv2_dnez"
>> +  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 
>> "register_operand"      "v")
>> +               (match_operand:DF 1 "csky_const_float0_operand" "i")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fcmpzned\t%0")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float convert instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +;; DF <- SF
>> +(define_insn "*fpuv2_extendsfdf2"
>> +  [(set (match_operand:DF          0 "register_operand" "=v")
>> +    (float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fstod\t%0, %1")
>> +
>> +;; SF <- DF
>> +(define_insn "*fpuv2_truncdfsf2"
>> +  [(set (match_operand:SF            0 "register_operand" "=v")
>> +    (float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fdtos\t%0, %1")
>> +
>> +;; SF <- SI
>> +(define_insn "*fpuv2_floatsisf2"
>> +  [(set (match_operand:SF       0 "register_operand" "=v")
>> +    (float:SF (match_operand:SI 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fsitos\t%0, %1")
>> +
>> +;; DF <- SI
>> +(define_insn "*fpuv2_floatsidf2"
>> +  [(set (match_operand:DF       0 "register_operand" "=v")
>> +    (float:DF (match_operand:SI 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fsitod\t%0, %1")
>> +
>> +;; SF <- unsigned SI
>> +(define_insn "*fpuv2_floatunssisf2"
>> +  [(set (match_operand:SF            0 "register_operand" "=v")
>> +    (unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fuitos\t%0, %1")
>> +
>> +;; DF <- unsigned SI
>> +(define_insn "*fpuv2_floatunssidf2"
>> +  [(set (match_operand:DF            0 "register_operand" "=v")
>> +    (unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fuitod\t%0, %1")
>> +
>> +;; SI <- SF
>> +(define_insn "*fpuv2_fix_truncsfsi2"
>> +  [(set (match_operand:SI     0 "register_operand" "=v")
>> +    (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fstosi.rz\t%0, %1")
>> +
>> +;; SI <- DF
>> +(define_insn "*fpuv2_fix_truncdfsi2"
>> +  [(set (match_operand:SI     0 "register_operand" "=v")
>> +    (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fdtosi.rz\t%0, %1")
>> +
>> +;; unsigned SI <- SF
>> +(define_insn "*fpuv2_fixuns_truncsfsi2"
>> +  [(set (match_operand:SI          0 "register_operand" "=v")
>> +    (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" 
>> "v"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "fstoui.rz\t%0, %1")
>> +
>> +;; unsigned SI <- DF
>> +(define_insn "*fpuv2_fixuns_truncdfsi2"
>> +  [(set (match_operand:SI          0 "register_operand" "=v")
>> +    (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" 
>> "v"))))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "fdtoui.rz\t%0, %1")
>> +
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float mov instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpuv2_movsf"
>> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r, 
>> r,m,v,r,Q,v,v,v")
>> +    (match_operand:SF 1 "general_operand"      " 
>> r,m,mF,r,r,v,v,Q,v,W"))]
>> +  "CSKY_ISA_FEATURE (fpv2_sf)"
>> +  "* return csky_output_move(insn, operands, SFmode);"
>> +)
>> +
>> +(define_insn "*fpuv2_movdf"
>> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, r,m, 
>> v,?r,Q,v,v,v")
>> +    (match_operand:DF 1 "general_operand"      " r,m,mF,r,?r, 
>> v,v,Q,v,m"))]
>> +  "CSKY_ISA_FEATURE (fpv2_df)"
>> +  "* return csky_output_movedouble(operands, DFmode);"
>> +  [(set (attr "length")
>> +    (symbol_ref "csky_get_movedouble_length (operands)"))]
>> +)
>> diff --git a/gcc/config/csky/csky_insn_fpuv3.md 
>> b/gcc/config/csky/csky_insn_fpuv3.md
>> new file mode 100644
>> index 0000000..053673c
>> --- /dev/null
>> +++ b/gcc/config/csky/csky_insn_fpuv3.md
>> @@ -0,0 +1,497 @@
>> +
>> +(define_c_enum "unspec" [
>> +  UNSPEC_MAXNM_F3
>> +  UNSPEC_MINNM_F3
>> +])
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float mov instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_movhf"
>> +  [(set (match_operand:HF 0 "nonimmediate_operand" 
>> "=r,r,v,r,m,r,Q,v,v,v, v")
>> +    (match_operand:HF 1 "general_operand"      " 
>> r,F,r,v,r,m,v,Q,v,W,Dv"))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "*
>> +  switch (which_alternative)
>> +    {
>> +    case 2:
>> +      return \"fmtvr.16\\t%0, %1\";
>> +    case 3:
>> +      return \"fmfvr.16\\t%0, %1\";
>> +    case 6:
>> +    case 7:
>> +    case 9:
>> +      return fpuv3_output_move(operands);
>> +    case 8:
>> +      return \"fmov.16\\t%0, %1\";
>> +    case 10:
>> +      return \"fmovi.16\\t%0, %1\";
>> +    case 1:
>> +      {
>> +    long bits;
>> +    rtx ops[4];
>> +
>> +    bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE 
>> (operands[1]), HFmode);
>> +    ops[0] = operands[0];
>> +    ops[1] = GEN_INT (bits);
>> +
>> +    output_asm_insn (\"lrw\\t%0, %1\", ops);
>> +    return \"\";
>> +      }
>> +    default:
>> +      return csky_output_move(insn, operands, HFmode);
>> +    }
>> +  "
>> +)
>> +
>> +(define_insn "*fpv3_movsf"
>> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r, 
>> r,m,v,r,Q,v,v,v, v")
>> +    (match_operand:SF 1 "general_operand"      " 
>> r,m,mF,r,r,v,v,Q,v,W,Dv"))]
>> +  "CSKY_ISA_FEATURE(fpv3_sf)"
>> +  "*
>> +  switch (which_alternative)
>> +    {
>> +    case 4:
>> +      return \"fmtvr.32.1\\t%0, %1\";
>> +    case 5:
>> +      return \"fmfvr.32.1\\t%0, %1\";
>> +    case 6:
>> +    case 7:
>> +    case 9:
>> +      return fpuv3_output_move(operands);
>> +    case 8:
>> +      return \"fmov.32\\t%0, %1\";
>> +    case 10:
>> +      return \"fmovi.32\\t%0, %1\";
>> +    default:
>> +      return csky_output_move(insn, operands, SFmode);
>> +    }
>> +  "
>> +)
>> +
>> +(define_insn "*fpv3_movdf"
>> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, 
>> r,m,v,?r,Q,v,v,v, v")
>> +    (match_operand:DF 1 "general_operand"      " 
>> r,m,mF,r,?r,v,v,Q,v,m,Dv"))]
>> +  "CSKY_ISA_FEATURE(fpv3_df)"
>> +  "*
>> +  switch (which_alternative)
>> +    {
>> +    case 4:
>> +      if (TARGET_BIG_ENDIAN)
>> +    return \"fmtvr.64\\t%0, %R1, %1\";
>> +      return \"fmtvr.64\\t%0, %1, %R1\";
>> +    case 5:
>> +      if (TARGET_BIG_ENDIAN)
>> +    return \"fmfvr.64\\t%R0, %0, %1\";
>> +      return \"fmfvr.64\\t%0, %R0, %1\";
>> +    case 6:
>> +    case 7:
>> +    case 9:
>> +      return fpuv3_output_move(operands);
>> +    case 8:
>> +      return \"fmov.64\\t%0, %1\";
>> +    case 10:
>> +      return \"fmovi.64\\t%0, %1\";
>> +    default:
>> +      return csky_output_movedouble(operands, DFmode);
>> +    }
>> +  "
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Mul instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_mul<mode>3"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "=v")
>> +    (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
>> +            (match_operand:F3ANY  2 "register_operand" " v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fmul.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float Muladd and mulsub instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_mula<mode>3"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "+v")
>> +    (plus:F3ANY (mult:F3ANY (match_operand:F3ANY  1 
>> "register_operand" " v")
>> +                (match_operand:F3ANY  2 "register_operand" " v"))
>> +            (match_dup 0)))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fmula.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +(define_insn "*fpv3_muls<mode>3"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "+v")
>> +    (minus:F3ANY (match_dup 0)
>> +             (mult:F3ANY (match_operand:F3ANY  1 "register_operand" 
>> " v")
>> +                 (match_operand:F3ANY  2 "register_operand" " v"))))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fmuls.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float fmula/fmuls/fnmula/fnmuls instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_fmuls_<mode>4"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "=v")
>> +    (fma:F3ANY (neg:F3ANY (match_operand:F3ANY  1 "register_operand" 
>> "v"))
>> +           (match_operand:F3ANY   2 "register_operand" "v")
>> +           (match_operand:F3ANY   3 "register_operand"  "0")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "ffmuls.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +(define_insn "*fpv3_fmula_<mode>4"
>> +  [(set (match_operand:F3ANY        0 "register_operand" "=v")
>> +    (fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
>> +           (match_operand:F3ANY 2 "register_operand" " v")
>> +           (match_operand:F3ANY 3 "register_operand" "0")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "ffmula.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +(define_insn "*fpv3_fnmula_<mode>4"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "=v")
>> +    (neg: F3ANY (fma:F3ANY (match_operand:F3ANY  1 
>> "register_operand" " v")
>> +                   (match_operand:F3ANY  2 "register_operand" " v")
>> +                   (match_operand:F3ANY  3 "register_operand" "0"))))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "ffnmula.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +(define_insn "*fpv3_fnmuls_<mode>4"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "=v")
>> +    (fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
>> +           (match_operand:F3ANY  2 "register_operand" " v")
>> +           (neg:F3ANY (match_operand:F3ANY  3 "register_operand" 
>> "0"))))]
>> +  "CSKY_ISA_FEATURE(fpv3_sf)"
>> +  "ffnmuls.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float div/recipe/sqrt instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_div<mode>3"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "=v")
>> +    (div:F3ANY (match_operand:F3ANY   1 "register_operand" " v")
>> +           (match_operand:F3ANY   2 "register_operand" " v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fdiv.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +(define_insn "*fpv3_recip<mode>3"
>> +  [(set (match_operand:F3ANY         0 "register_operand" "=v")
>> +    (div:F3ANY (match_operand:F3ANY  1 "csky_const_float1_operand" " 
>> i")
>> +           (match_operand:F3ANY  2 "register_operand" " v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "frecip.<f3t>\t%0, %2"
>> +)
>> +
>> +(define_insn "*fpv3_sqrt<mode>2"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "=v")
>> +    (sqrt:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fsqrt.<f3t>\t%0, %1"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float fmax/fmin instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "fmax<mode>3"
>> +  [(set (match_operand:F3ANY         0 "register_operand" "=v")
>> +    (unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
>> +               (match_operand:F3ANY  2 "register_operand" " v")]
>> +              UNSPEC_MAXNM_F3))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fmaxnm.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +(define_insn "fmin<mode>3"
>> +  [(set (match_operand:F3ANY         0 "register_operand" "=v")
>> +    (unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
>> +               (match_operand:F3ANY  2 "register_operand" " v")]
>> +              UNSPEC_MINNM_F3))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fminnm.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float compare instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_<zero_inst>_<mode>3"
>> +  [(set (reg:CC CSKY_CC_REGNUM)
>> +    (FCMPZ:CC (match_operand:F3ANY 0 "register_operand" "v")
>> +          (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
>> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +   "fcmp<zero_inst>.<f3t>\t%0"
>> +)
>> +
>> +(define_insn "*fpv3_<reg_inst>_<mode>3"
>> +  [(set (reg:CC CSKY_CC_REGNUM)
>> +    (FCMP:CC (match_operand:F3ANY 0 "register_operand" "v")
>> +         (match_operand:F3ANY 1 "register_operand" "v")))]
>> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +   "fcmp<reg_inst>.<f3t>\t%0, %1"
>> +)
>> +
>> +(define_insn "*fpv3_gt<mode>3"
>> +  [(set (reg:CC CSKY_CC_REGNUM)
>> +    (gt:CC (match_operand:F3ANY 0 "register_operand" "v")
>> +           (match_operand:F3ANY 1 "register_operand" "v")))]
>> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +   "fcmplt.<f3t>\t%1, %0"
>> +)
>> +
>> +(define_insn "*fpv3_le<mode>3"
>> +  [(set (reg:CC CSKY_CC_REGNUM)
>> +    (le:CC (match_operand:F3ANY 0 "register_operand" "v")
>> +           (match_operand:F3ANY 1 "register_operand" "v")))]
>> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +   "fcmphs.<f3t>\t%1, %0"
>> +)
>> +
>> +(define_insn "*fpv3_unordered"
>> +  [(set (reg:CC CSKY_CC_REGNUM)
>> +    (unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
>> +              (match_operand:F3ANY 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fcmpuo.<f3t>\t%0, %1")
>> +
>> +(define_insn "*fpv3_unordered_zero"
>> +  [(set (reg:CC CSKY_CC_REGNUM)
>> +    (unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
>> +              (match_operand:F3ANY 1 "csky_const_float0_operand" 
>> "i")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fcmpuoz.<f3t>\t%0")
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float ADD instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_add<mode>3"
>> +  [(set (match_operand:F3ANY          0 "register_operand" "=v")
>> +    (plus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
>> +            (match_operand:F3ANY  2 "register_operand" " v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fadd.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float SUB instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_sub<mode>3"
>> +  [(set (match_operand:F3ANY           0 "register_operand" "=v")
>> +    (minus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
>> +             (match_operand:F3ANY  2 "register_operand" " v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fsub.<f3t>\t%0, %1, %2"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float NEG instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_neg<mode>2"
>> +  [(set (match_operand:F3ANY         0 "register_operand" "=v")
>> +    (neg:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fneg.<f3t>\t%0, %1"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float ABS instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +(define_insn "*fpv3_abs<mode>2"
>> +  [(set (match_operand:F3ANY         0 "register_operand" "=v")
>> +    (abs:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fabs.<f3t>\t%0, %1"
>> +)
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float common convert instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +;; SF <- HF
>> +(define_insn "*fpv3_extendhfsf2"
>> +  [(set (match_operand:SF          0 "register_operand" "=v")
>> +    (float_extend:SF (match_operand:HF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "fhtos\t%0, %1")
>> +
>> +;; HF <- SF
>> +(define_insn "*fpv3_truncsfhf2"
>> +  [(set (match_operand:HF             0 "register_operand" "=v")
>> +    (float_truncate:HF (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "fstoh\t%0, %1")
>> +
>> +;; DF <- SF
>> +(define_insn "*fpv3_extendsfdf2"
>> +  [(set (match_operand:DF          0 "register_operand" "=v")
>> +    (float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_df)"
>> +  "fstod\t%0, %1")
>> +
>> +;; SF <- DF
>> +(define_insn "*fpv3_truncdfsf2"
>> +  [(set (match_operand:SF            0 "register_operand" "=v")
>> +    (float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_df)"
>> +  "fdtos\t%0, %1")
>> +
>> +;; DF,SF,HF <- unsigned SI,SI
>> +(define_insn "*fpv3_float<floatsuop>si<mode>2"
>> +  [(set (match_operand:F3ANY       0 "register_operand" "=v")
>> +    (FLOAT_SU:F3ANY (match_operand:SI 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fitof.<floatsu>32.f<f3t>\t%0, %1")
>> +
>> +;; HF <- unsigned HI,HI
>> +(define_insn "*fpv3_float<floatsuop>hihf2"
>> +  [(set (match_operand:HF       0 "register_operand" "=v")
>> +    (FLOAT_SU:HF (match_operand:HI 1 "register_operand" "v")))]
>> +  "CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
>> +  "fitof.<floatsu>16.f16\t%0, %1")
>> +
>> +;; unsigned SI,SI <- DF,SF,HF
>> +(define_insn "*fpv3_fix<fixsuop>_trunc<mode>si2"
>> +  [(set (match_operand:SI        0 "register_operand" "=v")
>> +    (FIX_SU:SI (fix:F3ANY (match_operand:F3ANY 1 "register_operand" 
>> "v"))))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fftoi.f<f3t>.<fixsu>32.rz\t%0, %1")
>> +
>> +;; 
>> -------------------------------------------------------------------------
>> +;; Float complex convert instructions
>> +;; 
>> -------------------------------------------------------------------------
>> +
>> +;; Fixed point to floating point conversions.
>> +
>> +;(define_insn "*combine_fcvt_fixed16_<mode>"
>> +;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
>> +;    (mult:F3ANY (float:F3ANY (match_operand:HI 1 "register_operand" 
>> "0"))
>> +;           (match_operand 2
>> +;            "const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
>> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
>> +;   && CSKY_ISA_FEATURE(fpv3_hi)"
>> +;  "fxtof.s16.f<f3t>\t%0, %1, %v2")
>> +;
>> +;(define_insn "*combine_fcvt_fixed32_<mode>"
>> +;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
>> +;    (mult:F3ANY (float:F3ANY (match_operand:SI 1 "register_operand" 
>> "0"))
>> +;           (match_operand 2
>> +;            "const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
>> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
>> +;  "fxtof.s32.f<f3t>\t%0, %1, %v2")
>> +;
>> +;(define_insn "*combine_fcvt_unfixed16_<mode>"
>> +;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
>> +;    (mult:F3ANY (unsigned_float:F3ANY (match_operand:HI 1 
>> "register_operand" "0"))
>> +;           (match_operand 2
>> +;            "const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
>> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
>> +;   && CSKY_ISA_FEATURE(fpv3_hi)"
>> +;  "fxtof.u16.f<f3t>\t%0, %1, %v2")
>> +;
>> +;(define_insn "*combine_fcvt_unfixed32_<mode>"
>> +;  [(set (match_operand:F3ANY 0 "register_operand" "=v")
>> +;    (mult:F3ANY (unsigned_float:F3ANY (match_operand:SI 1 
>> "register_operand" "0"))
>> +;           (match_operand 2
>> +;            "const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
>> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
>> +;  "fxtof.u32.f<f3t>\t%0, %1, %v2")
>> +
>> +;; Floating point to fixed point conversions.
>> +
>> +;(define_insn "*combine_fcvt<mode>_fixed16"
>> +;  [(set (match_operand:HI 0 "register_operand" "=v")
>> +;    (fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 
>> "register_operand" "0")
>> +;                (match_operand 2
>> +;                 "const_double_fcvt_power_of_two_hq" "Du")))))]
>> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
>> +;   && CSKY_ISA_FEATURE(fpv3_hi)"
>> +;  "fftox.f<f3t>.s16\t%0, %1, %v2"
>> +; )
>> +;
>> +;(define_insn "*combine_fcvt<mode>_fixed32"
>> +;  [(set (match_operand:SI 0 "register_operand" "=v")
>> +;    (fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 
>> "register_operand" "0")
>> +;                (match_operand 2
>> +;                 "const_double_fcvt_power_of_two_sq" "Du")))))]
>> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
>> +;  "fftox.f<f3t>.s32\t%0, %1, %v2"
>> +; )
>> +;
>> +;(define_insn "*combine_fcvt<mode>_unfixed16"
>> +;  [(set (match_operand:HI 0 "register_operand" "=v")
>> +;    (unsigned_fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 
>> "register_operand" "0")
>> +;                     (match_operand 2
>> +;                      "const_double_fcvt_power_of_two_hq" "Du")))))]
>> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
>> +;   && CSKY_ISA_FEATURE(fpv3_hi)"
>> +;  "fftox.f<f3t>.u16\t%0, %1, %v2"
>> +; )
>> +;
>> +;(define_insn "*combine_fcvt<mode>_unfixed32"
>> +;  [(set (match_operand:SI 0 "register_operand" "=v")
>> +;    (unsigned_fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 
>> "register_operand" "0")
>> +;                     (match_operand 2
>> +;                      "const_double_fcvt_power_of_two_sq" "Du")))))]
>> +;  "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
>> +;  "fftox.f<f3t>.u32\t%0, %1, %v2"
>> +; )
>> +
>> +;; conversions need to be rounding to nearest.
>> +
>> +(define_insn "l<frm_pattern><fixsuop><mode>si2"
>> +  [(set (match_operand:SI 0 "register_operand" "=v")
>> +    (FIX_SU:SI (unspec:F3ANY [(match_operand:F3ANY 1 
>> "register_operand" "0")]
>> +                   FRM)))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fftoi.f<f3t>.<fixsu>32<rm>\t%0, %1"
>> +)
>> +
>> +(define_insn "<frm_pattern><mode>2"
>> +  [(set (match_operand:F3ANY 0 "register_operand" "=v")
>> +    (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")] 
>> FRMF))]
>> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
>> +  "fftofi.f<f3t><rm>\t%0, %1"
>> +)
>> +
>> +;; Write Floating-point Control Register.
>> +(define_insn "csky_setfcrsi"
>> +  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 
>> VUNSPEC_SET_FCR)]
>> +  "CSKY_ISA_FEATURE(fcr)"
>> +  "mtcr\t%0, fcr"
>> +)
>> +
>> +;; Read Floating-point Control Register.
>> +(define_insn "csky_getfcrsi"
>> +  [(set (match_operand:SI 0 "register_operand" "=r")
>> +    (unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FCR))]
>> +  "CSKY_ISA_FEATURE(fcr)"
>> +  "mfcr\t%0, fcr"
>> +)
>> +
>> +;; Insert Floating-point Control Register.
>> +(define_insn "csky_insfcrsi"
>> +  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
>> +             (match_operand:SI 1 "const_int_operand" "i")
>> +             (match_operand:SI 2 "const_int_operand" 
>> "i")]VUNSPEC_INS_FCR)
>> +   (clobber (reg: SI 13))]
>> +  "CSKY_ISA_FEATURE(fcr)"
>> +  {
>> +    operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL 
>> (operands[1]) - 1);
>> +    return "mfcr\tt1, fcr\n\tins\tt1, %0, %1, %2\n\tmtcr\tt1, fcr";
>> +  }
>> +)
>> diff --git a/gcc/config/csky/csky_isa.def b/gcc/config/csky/csky_isa.def
>> index 5edce16..5849819 100644
>> --- a/gcc/config/csky/csky_isa.def
>> +++ b/gcc/config/csky/csky_isa.def
>> @@ -32,6 +32,7 @@ CSKY_ISA (7E10,     "Extended insns for arch 
>> ck810     from ck807")
>>     /* Special insns */
>>   CSKY_ISA (div,      "divide insns")
>> +CSKY_ISA (fcr,      "Control the fcr register")
>>     /* Extended insns */
>>   CSKY_ISA (dsp,     "Extended insns for DSP")
>> @@ -41,6 +42,11 @@ CSKY_ISA (fpv2_sf,    "Single precision operations 
>> supported")
>>   CSKY_ISA (fpv2_df,    "Double precision operations supported")
>>   CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
>>   +CSKY_ISA (fpv3_hi,    "half word for fpu convert supported")
>> +CSKY_ISA (fpv3_hf,    "half precision operations supported")
>> +CSKY_ISA (fpv3_sf,    "Single precision operations supported")
>> +CSKY_ISA (fpv3_df,    "Double precision operations supported")
>> +
>>   /* Specific insns mode */
>>   #ifdef    CSKY_ISA_MACRO
>>   #define CSKY_ISA_CK801        CSKY_ISA_FEATURE_GET (E1)
>> @@ -50,10 +56,19 @@ CSKY_ISA (fpv2_divd,  "Double precision div 
>> operations supported")
>>   #define CSKY_ISA_CK803R1    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET 
>> (3E3r1)
>>   #define CSKY_ISA_CK807        CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET 
>> (3E7)
>>   #define CSKY_ISA_CK810        CSKY_ISA_CK807, CSKY_ISA_FEATURE_GET 
>> (7E10)
>> +#define CSKY_ISA_CK860      CSKY_ISA_CK810, CSKY_ISA_FEATURE_GET(3E3r1)
>>     #define CSKY_ISA_DSP        CSKY_ISA_FEATURE_GET (dsp)
>>     #define CSKY_ISA_FPv2_SF    CSKY_ISA_FEATURE_GET (fpv2_sf)
>>   #define CSKY_ISA_FPv2        CSKY_ISA_FPv2_SF, CSKY_ISA_FEATURE_GET 
>> (fpv2_df)
>>   #define CSKY_ISA_FPv2_DIVD  CSKY_ISA_FPv2, CSKY_ISA_FEATURE_GET 
>> (fpv2_divd)
>> +
>> +#define CSKY_ISA_FPv3_HF    CSKY_ISA_FEATURE_GET (fpv3_hf), \
>> +                            CSKY_ISA_FEATURE_GET (fpv3_hi)
>> +#define CSKY_ISA_FPv3_HSF   CSKY_ISA_FPv3_HF, \
>> +                            CSKY_ISA_FEATURE_GET (fpv3_sf)
>> +#define CSKY_ISA_FPv3_SDF   CSKY_ISA_FEATURE_GET (fpv3_sf), \
>> +                            CSKY_ISA_FEATURE_GET (fpv3_df)
>> +#define CSKY_ISA_FPv3       CSKY_ISA_FPv3_HF, CSKY_ISA_FPv3_SDF
>>   #endif
>> diff --git a/gcc/config/csky/csky_tables.opt 
>> b/gcc/config/csky/csky_tables.opt
>> index 3501f90..ca113dd 100644
>> --- a/gcc/config/csky/csky_tables.opt
>> +++ b/gcc/config/csky/csky_tables.opt
>> @@ -194,6 +194,12 @@ Enum(csky_processor_type) String(ck810ft) Value( 
>> TARGET_CPU_ck810ff)
>>   EnumValue
>>   Enum(csky_processor_type) String(ck810ftv) Value( TARGET_CPU_ck810ftv)
>>   +EnumValue
>> +Enum(csky_processor_type) String(ck860) Value( TARGET_CPU_ck860)
>> +
>> +EnumValue
>> +Enum(csky_processor_type) String(ck860f) Value( TARGET_CPU_ck860f)
>> +
>>   Enum
>>   Name(csky_arch) Type(int)
>>   Known CSKY architectures (for use with the -march= option):
>> @@ -213,6 +219,9 @@ Enum(csky_arch) String(ck807) Value(3)
>>   EnumValue
>>   Enum(csky_arch) String(ck810) Value(4)
>>   +EnumValue
>> +Enum(csky_arch) String(ck860) Value(5)
>> +
>>   Enum
>>   Name(csky_fpu) Type(enum csky_fpu_type)
>>   Known CSKY FPUs (for use with the -mfpu= option):
>> @@ -227,4 +236,16 @@ EnumValue
>>   Enum(csky_fpu) String(fpv2_divd) Value(TARGET_FPU_fpv2_divd)
>>     EnumValue
>> +Enum(csky_fpu) String(fpv3_hf) Value(TARGET_FPU_fpv3_hf)
>> +
>> +EnumValue
>> +Enum(csky_fpu) String(fpv3_hsf) Value(TARGET_FPU_fpv3_hsf)
>> +
>> +EnumValue
>> +Enum(csky_fpu) String(fpv3_sdf) Value(TARGET_FPU_fpv3_sdf)
>> +
>> +EnumValue
>> +Enum(csky_fpu) String(fpv3) Value(TARGET_FPU_fpv3)
>> +
>> +EnumValue
>>   Enum(csky_fpu) String(auto) Value(TARGET_FPU_auto)
>> diff --git a/gcc/config/csky/predicates.md 
>> b/gcc/config/csky/predicates.md
>> index 4ffecb0..878446d 100644
>> --- a/gcc/config/csky/predicates.md
>> +++ b/gcc/config/csky/predicates.md
>> @@ -294,5 +294,4 @@
>>   })
>>     (define_special_predicate "csky_float_comparison_operator"
>> -  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
>> -           unordered,ordered"))
>> +  (match_code "eq,ne,le,lt,ge,gt,unordered,ordered"))
>> diff --git a/gcc/config/csky/t-csky-elf b/gcc/config/csky/t-csky-elf
>> index bbdf286..4e7fcbe 100644
>> --- a/gcc/config/csky/t-csky-elf
>> +++ b/gcc/config/csky/t-csky-elf
>> @@ -27,8 +27,8 @@ MULTILIB_MATCHES      = mbig-endian=EB
>>   MULTILIB_EXCEPTIONS   =
>>     # Arch variants.
>> -MULTILIB_OPTIONS     += 
>> mcpu=ck802/mcpu=ck801/mcpu=ck803f/mcpu=ck807f/mcpu=ck810f
>> -MULTILIB_DIRNAMES    += ck802 ck801 ck803 ck807 ck810
>> +MULTILIB_OPTIONS     += 
>> mcpu=ck802/mcpu=ck801/mcpu=ck803f/mcpu=ck807f/mcpu=ck810f/mcpu=ck860f
>> +MULTILIB_DIRNAMES    += ck802 ck801 ck803 ck807 ck810 ck860
>>     # For arch ck802.
>>   MULTILIB_MATCHES     += mcpu?ck802=march?ck802
>> @@ -100,6 +100,11 @@ MULTILIB_MATCHES     += mcpu?ck807f=march?ck807ef
>>   MULTILIB_MATCHES     += mcpu?ck807f=march?ck807
>>   MULTILIB_MATCHES     += mcpu?ck807f=mcpu?ck807
>>   +# For arch ck860
>> +MULTILIB_MATCHES     += mcpu?ck860f=march?ck860
>> +MULTILIB_MATCHES     += mcpu?ck860f=mcpu?ck860
>> +MULTILIB_MATCHES     += mcpu?ck860f=mcpu?c860
>> +
>>   # For option -mfloat-abi=
>>   MULTILIB_OPTIONS     += 
>> mfloat-abi=soft/mfloat-abi=softfp/mfloat-abi=hard
>>   MULTILIB_DIRNAMES    += soft soft-fp hard-fp
>> diff --git a/gcc/config/csky/t-csky-linux b/gcc/config/csky/t-csky-linux
>> index 9435b7a..0730c3a 100644
>> --- a/gcc/config/csky/t-csky-linux
>> +++ b/gcc/config/csky/t-csky-linux
>> @@ -21,11 +21,11 @@
>>       MULTILIB_EXCEPTIONS  =
>> -CSKY_MULTILIB_OSDIRNAMES = mfloat-abi.softfp=/soft-fp 
>> mfloat-abi.hard=/hard-fp mfloat-abi.soft=/. mcpu.ck810f=/. 
>> mcpu.ck807f=/ck807
>> +CSKY_MULTILIB_OSDIRNAMES = mfloat-abi.softfp=/soft-fp 
>> mfloat-abi.hard=/hard-fp mfloat-abi.soft=/. mcpu.ck810f=/. 
>> mcpu.ck807f=/ck807 mcpu.ck860f=/ck860
>>     # Arch variants.
>> -MULTILIB_OPTIONS     += mcpu=ck810f/mcpu=ck807f
>> -MULTILIB_DIRNAMES    += ck810 ck807
>> +MULTILIB_OPTIONS     += mcpu=ck810f/mcpu=ck807f/mcpu=ck860f
>> +MULTILIB_DIRNAMES    += ck810 ck807 ck860
>>     # For ck807.
>>   MULTILIB_MATCHES     += mcpu?ck807f=march?ck807
>> @@ -41,6 +41,11 @@ MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810vf
>>   MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810ft
>>   MULTILIB_MATCHES     += mcpu?ck810f=mcpu?ck810vft
>>   +# For ck860
>> +MULTILIB_MATCHES     += mcpu?ck860f=march?ck860
>> +MULTILIB_MATCHES     += mcpu?ck860f=mcpu?ck860
>> +MULTILIB_MATCHES     += mcpu?ck860f=mcpu?c860
>> +
>>   # For option -mfloat-abi=
>>   MULTILIB_OPTIONS     += 
>> mfloat-abi=soft/mfloat-abi=softfp/mfloat-abi=hard
>>   MULTILIB_DIRNAMES    += soft soft-fp hard-fp
>> diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
>> index d166a0d..11b5868 100644
>> --- a/gcc/doc/md.texi
>> +++ b/gcc/doc/md.texi
>> @@ -2258,6 +2258,14 @@ Vector registers.
>>     @item z
>>   Stack pointer register (SP).
>> +
>> +@item Q
>> +A memory address which uses a base register with a short offset
>> +or with a index register with its scale.
>> +
>> +@item W
>> +A memory address which uses a base register with a index register
>> +with its scale.
>>   @end table
>>     @ifset INTERNALS

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] C-SKY: Add fpuv3 instructions and CK860 arch
  2020-08-27  9:33 gengqi
@ 2020-09-07 11:27 ` Xianmiao Qu
  0 siblings, 0 replies; 5+ messages in thread
From: Xianmiao Qu @ 2020-09-07 11:27 UTC (permalink / raw)
  To: gengqi, gcc-patches; +Cc: gengq

Hi Gengqi,

Is this patch based on the master branch? I cannot apply it successfully.


Cooper


On 8/27/20 5:33 PM, gengqi via Gcc-patches wrote:
> From: gengq <qi_geng@c-sky.com>
>
> gcc/ChangeLog:
>
> 	* config/csky/constraints.md (W): New constriant for mem operand with
> 	a base reg with a index register.
> 	(Q): Renamed and modified "csky_valid_fpuv2_mem_operand" to
> 	"csky_valid_mem_constraint_operand" to deal with both "Q" and "W"
> 	constraint.
> 	(Dv): New constraint for const double value that can be used at fmovi
> 	instruction.
> 	* config/csky/csky-modes.def (HFmode): New mode.
> 	* config/csky/csky-protos.h (csky_valid_mem_constraint_operand):
> 	Declare.
> 	(get_output_csky_movedouble_length): Declare.
> 	(fpuv3_output_move): Declare.
> 	(fpuv3_const_double): Declare.
> 	* config/csky/csky.c (csky_option_override): New arch CK860 with fpv3.
> 	(decompose_csky_address): Robustness adjust.
> 	(csky_print_operand): New "CONST_DOUBLE" operand.
> 	(csky_output_move): New support for fpv3 instructions.
> 	(get_output_csky_movedouble_length): New function.
> 	(fpuv3_output_move): New function.
> 	(fpuv3_const_double): New function.
> 	(csky_emit_compare): New cover for float comparsion.
> 	(csky_emit_compare_float): Refine.
> 	(csky_valid_mem_constraint_operand): Rename from
> 	"csky_valid_fpuv2_mem_operand" and new support for constraint "W".
> 	(ck860_rtx_costs): New function.
> 	(csky_rtx_costs): New subcall for CK860.
> 	* gcc/config/csky/csky.h (TARGET_TLS): Add CK860.
> 	* gcc/config/csky/csky.md (movsf): Delete, and achieve it at
> 	csky_insn_fpu.md.
> 	(ck801_movsf): Delete, and achieve it at csky_insn_fpu.md.
> 	(csky_movsf): Delete, and achieve it at csky_insn_fpu.md.
> 	(movdf): Delete, achieve it at csky_insn_fpu.md.
> 	(ck801_movdf): Delete, and achieve it at csky_insn_fpu.md.
> 	(csky_movdf): Delete, and achieve it at csky_insn_fpu.md.
> 	(csky_movsf_fpv2): Delete, and achieve it at csky_insn_fpuv2.md.
> 	(csky_movdf_fpv2): Delete, and achieve it at csky_insn_fpuv2.md.
> 	(movsicc): Refine. Use "comparison_operatior" instead of
> 	"ordered_comparison_operatior".
> 	(addsicc): Likewise.
> 	* config/csky/csky_cores.def (CK860): New arch and cpu.
> 	(fpv3_hf, fpv3_hsf, fpv3_sdf, fpv3): New fpus.
> 	* config/csky/csky_insn_fpu.md: Refactor. For fpuv2, separate all float
> 	patterns into emit-patterns and match-patterns, remain the
> 	emit-patterns here, and move the match-patterns to csky_insn_fpuv2.md.
> 	For fpuv3, add patterns and fuse part of them with the fpuv2's.
> 	* config/csky/csky_insn_fpuv2.md: New file for fpuv2 instructions.
> 	* config/csky/csky_insn_fpuv3.md: New flie and new patterns for fpuv3
> 	isntructions.
> 	* config/csky/csky_isa.def (fcr): New isa.
> 	(fpv3_hi, fpv3_hf, fpv3_sf, fpv3_df): New isa.
> 	(CK860): New definition.
> 	* gcc/config/csky/csky_tables.opt (ck860): New processors ck860,
> 	ck860f. And new arch ck860.
> 	(fpv3_hf, fpv3_hsf, fpv3_sdf, fpv3): New fpus.
> 	* config/csky/predicates.md (csky_float_comparsion_operator): Delete
> 	"geu", "gtu", "leu", "ltu", which will never appear at float
> 	comparison.
> 	* doc/md.texi: Add "Q" and "W" constraints for C-SKY.
>
> ---
>   gcc/config/csky/constraints.md     |  13 +-
>   gcc/config/csky/csky-modes.def     |   2 +
>   gcc/config/csky/csky-protos.h      |   7 +-
>   gcc/config/csky/csky.c             | 528 +++++++++++++++----
>   gcc/config/csky/csky.h             |   2 +-
>   gcc/config/csky/csky.md            | 120 +----
>   gcc/config/csky/csky_cores.def     |  13 +
>   gcc/config/csky/csky_insn_fpu.md   | 797 ++++++++++++-----------------
>   gcc/config/csky/csky_insn_fpuv2.md | 470 +++++++++++++++++
>   gcc/config/csky/csky_insn_fpuv3.md | 418 +++++++++++++++
>   gcc/config/csky/csky_isa.def       |  15 +
>   gcc/config/csky/csky_tables.opt    |  21 +
>   gcc/config/csky/predicates.md      |   3 +-
>   gcc/doc/md.texi                    |   8 +
>   14 files changed, 1752 insertions(+), 665 deletions(-)
>   create mode 100644 gcc/config/csky/csky_insn_fpuv2.md
>   create mode 100644 gcc/config/csky/csky_insn_fpuv3.md
>
> diff --git a/gcc/config/csky/constraints.md b/gcc/config/csky/constraints.md
> index b9990b7dac9..874f698411b 100644
> --- a/gcc/config/csky/constraints.md
> +++ b/gcc/config/csky/constraints.md
> @@ -34,7 +34,11 @@
>   
>   (define_memory_constraint "Q"
>     "Memory operands with base register, index register and short displacement for FPUV2"
> -  (match_test "csky_valid_fpuv2_mem_operand (op)"))
> +  (match_test "csky_valid_mem_constraint_operand (op, \"Q\")"))
> +
> +(define_memory_constraint "W"
> +  "memory operands with base register, index register"
> +  (match_test "csky_valid_mem_constraint_operand (op, \"W\")"))
>   
>   (define_constraint "R"
>     "Memory operands whose address is a label_ref"
> @@ -172,3 +176,10 @@
>     "Constant in range [-8, -1]"
>     (and (match_code "const_int")
>          (match_test "CSKY_CONST_OK_FOR_US (ival)")))
> +
> +(define_constraint "Dv"
> + "@VFPv3
> +  A const_double which can be used with a VFP fmovi
> +  instruction."
> + (and (match_code "const_double")
> +      (match_test "fpuv3_const_double_rtx (op)")))
> diff --git a/gcc/config/csky/csky-modes.def b/gcc/config/csky/csky-modes.def
> index b76829fc2ac..ec5ee093674 100644
> --- a/gcc/config/csky/csky-modes.def
> +++ b/gcc/config/csky/csky-modes.def
> @@ -1,3 +1,5 @@
> +/* Float modes.  */
> +FLOAT_MODE (HF, 2, ieee_half_format);        /* Half-precision floating point */
>   
>   /* Vector modes.  */
>   VECTOR_MODES (INT, 4);  /* V4QI V2HI */
> diff --git a/gcc/config/csky/csky-protos.h b/gcc/config/csky/csky-protos.h
> index 2c023996d58..4ba59cc9b28 100644
> --- a/gcc/config/csky/csky-protos.h
> +++ b/gcc/config/csky/csky-protos.h
> @@ -30,7 +30,7 @@ extern void csky_cpu_cpp_builtins (cpp_reader *);
>   extern bool csky_inlinable_constant (HOST_WIDE_INT value);
>   extern bool csky_shifted_imm8_constant (unsigned HOST_WIDE_INT,
>   					unsigned int *, unsigned int *);
> -extern bool csky_valid_fpuv2_mem_operand (rtx);
> +extern bool csky_valid_mem_constraint_operand (rtx, const char*);
>   
>   extern bool csky_minipool_load_p (rtx_insn *);
>   extern const char *csky_output_move (rtx insn, rtx *, machine_mode);
> @@ -70,4 +70,9 @@ extern int csky_default_branch_cost (bool, bool);
>   extern bool csky_default_logical_op_non_short_circuit (void);
>   
>   extern void csky_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
> +extern int get_output_csky_movedouble_length(rtx operands[]);
> +
> +/* The functions was used for fpuv3.  */
> +extern const char *fpuv3_output_move (rtx *operands);
> +extern int fpuv3_const_double_rtx (rtx);
>   #endif /* GCC_CSKY_PROTOS_H */
> diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
> index 4de8aee4e77..ac082e06782 100644
> --- a/gcc/config/csky/csky.c
> +++ b/gcc/config/csky/csky.c
> @@ -329,15 +329,15 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
>         builtin_define ("__csky_hard_float__");
>         builtin_define ("__CSKY_HARD_FLOAT__");
>         if (TARGET_HARD_FLOAT_ABI)
> -        {
> -          builtin_define ("__csky_hard_float_abi__");
> -          builtin_define ("__CSKY_HARD_FLOAT_ABI__");
> -        }
> +	{
> +	  builtin_define ("__csky_hard_float_abi__");
> +	  builtin_define ("__CSKY_HARD_FLOAT_ABI__");
> +	}
>         if (TARGET_SINGLE_FPU)
> -        {
> -          builtin_define ("__csky_hard_float_fpu_sf__");
> -          builtin_define ("__CSKY_HARD_FLOAT_FPU_SF__");
> -        }
> +	{
> +	  builtin_define ("__csky_hard_float_fpu_sf__");
> +	  builtin_define ("__CSKY_HARD_FLOAT_FPU_SF__");
> +	}
>       }
>     else
>       {
> @@ -698,7 +698,7 @@ csky_default_logical_op_non_short_circuit (void)
>   #define	 TARGET_SCHED_ADJUST_COST csky_sched_adjust_cost
>   
>   /******************************************************************
> - *           Construct vector Type and Builtin Function           *
> + *	   Construct vector Type and Builtin Function	   *
>    ******************************************************************/
>   
>   #undef TARGET_VECTOR_MODE_SUPPORTED_P
> @@ -853,6 +853,7 @@ Mfix *minipool_fix_tail;
>   Mfix *minipool_barrier;
>   
>   /* Allow GC scanning of the minipool obstack.  */
> +
>   static void
>   csky_add_gc_roots (void)
>   {
> @@ -862,6 +863,7 @@ csky_add_gc_roots (void)
>   
>   /* Implement TARGET_CONSTANT_ALIGNMENT.
>      Make strings word-aligned so strcpy from constants will be faster.  */
> +
>   static HOST_WIDE_INT
>   csky_constant_alignment (const_tree exp, HOST_WIDE_INT align)
>   {
> @@ -1125,6 +1127,7 @@ get_csky_barrier_cost (rtx_insn *insn)
>      (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
>      Create the barrier by inserting a jump and add a new fix entry for
>      it.  */
> +
>   static Mfix *
>   create_csky_fix_barrier (Mfix *fix, Mfix *fix_next,
>   			 HOST_WIDE_INT max_address)
> @@ -1471,6 +1474,7 @@ csky_compute_pushpop_length (rtx *operands)
>   }
>   
>   /* Emit constant pools for -mconstpool.  */
> +
>   static void
>   csky_emit_constant_pools (void)
>   {
> @@ -1812,6 +1816,7 @@ csky_initial_elimination_offset (int from, int to)
>      CUM is a variable of type CUMULATIVE_ARGS which gives info about
>       the preceding args and about the function being called.
>      ARG is a description of the argument.  */
> +
>   static rtx
>   csky_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>   {
> @@ -1825,9 +1830,9 @@ csky_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
>         reg = pcum->freg;
>   
>         if (reg < CSKY_NPARM_FREGS)
> -        return gen_rtx_REG (mode, CSKY_FIRST_VFP_REGNUM + reg);
> +	return gen_rtx_REG (mode, CSKY_FIRST_VFP_REGNUM + reg);
>         else
> -        return NULL_RTX;
> +	return NULL_RTX;
>       }
>   
>     if (reg < CSKY_NPARM_REGS)
> @@ -1854,8 +1859,8 @@ csky_num_arg_regs (machine_mode mode, const_tree type, bool is_stdarg)
>         && !is_stdarg)
>       {
>         if (CSKY_VREG_MODE_P(mode)
> -          && !TARGET_SINGLE_FPU)
> -        return ((CSKY_NUM_WORDS (size) + 1) / 2);
> +	  && !TARGET_SINGLE_FPU)
> +	return ((CSKY_NUM_WORDS (size) + 1) / 2);
>       }
>   
>     return CSKY_NUM_WORDS (size);
> @@ -1937,6 +1942,7 @@ csky_function_value (const_tree type, const_tree func,
>   
>   
>   /* Implement TARGET_LIBCALL_VALUE.  */
> +
>   static rtx
>   csky_libcall_value (machine_mode mode,
>   		    const_rtx libcall ATTRIBUTE_UNUSED)
> @@ -1957,7 +1963,7 @@ csky_function_value_regno_p (const unsigned int regno)
>   {
>     if (regno == CSKY_FIRST_RET_REGNUM
>         || (TARGET_HARD_FLOAT_ABI
> -          && regno == CSKY_FIRST_VFP_REGNUM))
> +	  && regno == CSKY_FIRST_VFP_REGNUM))
>       return true;
>     return false;
>   }
> @@ -1965,6 +1971,7 @@ csky_function_value_regno_p (const unsigned int regno)
>   
>   /* Return an RTX indicating where the return address to the
>      calling function can be found.  */
> +
>   rtx
>   csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
>   {
> @@ -1980,6 +1987,7 @@ csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
>      that must be put in registers. The value must be zero for arguments
>      that are passed entirely in registers or
>      that are entirely pushed on the stack.  */
> +
>   static int
>   csky_arg_partial_bytes (cumulative_args_t pcum_v, const function_arg_info &arg)
>   {
> @@ -2214,6 +2222,7 @@ csky_conditional_register_usage (void)
>   }
>   
>   /* Implement TARGET_HARD_REGNO_NREGS.  */
> +
>   static unsigned int
>   csky_hard_regno_nregs (unsigned int regno, machine_mode mode)
>   {
> @@ -2277,6 +2286,7 @@ csky_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
>   /* Implement TARGET_MODES_TIEABLE_P.  We can't tie DFmode with other modes
>      when V_REGs might be in use because those registers mess with the stored
>      bits.  */
> +
>   static bool
>   csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
>   {
> @@ -2288,6 +2298,7 @@ csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
>   /* Implement TARGET_CAN_CHANGE_MODE_CLASS.
>      V_REG registers can't do subreg as all values are reformatted to
>      internal precision.  */
> +
>   static bool
>   csky_can_change_mode_class (machine_mode from,
>   			    machine_mode to,
> @@ -2422,6 +2433,7 @@ csky_spill_class (reg_class_t rclass, machine_mode mode ATTRIBUTE_UNUSED)
>   
>   /* Convert a static initializer array of feature bits to sbitmap
>      representation.  */
> +
>   static void
>   csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
>   {
> @@ -2433,6 +2445,7 @@ csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
>   
>   /* Configure a build target TARGET from the user-specified options OPTS and
>      OPTS_SET.  */
> +
>   static void
>   csky_configure_build_target (struct csky_build_target *target,
>   			     struct cl_target_option *opts,
> @@ -2524,7 +2537,9 @@ csky_option_override (void)
>   
>     csky_base_arch = csky_active_target.base_arch;
>   
> -  if (flag_pic && !(CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK807)))
> +  if (flag_pic && !(CSKY_TARGET_ARCH (CK807)
> +		   || CSKY_TARGET_ARCH (CK810)
> +		   || CSKY_TARGET_ARCH (CK860)))
>       {
>         flag_pic = 0;
>         warning (0, "%qs is not supported by arch %s",
> @@ -2542,19 +2557,21 @@ csky_option_override (void)
>   	  bool ok;
>   	  int fpu_index;
>   
> -#ifdef CSKY_FPUTYPE_DEFAULT
> -	  target_fpu_name = CSKY_FPUTYPE_DEFAULT;
> -#else
> -	  target_fpu_name = "fpv2";
> -#endif
> -
>   	  if (csky_active_target.core_name != NULL
>   	      && !strchr (csky_active_target.core_name, 'f'))
>   	    target_fpu_name = "auto";
>   	  else if (CSKY_TARGET_ARCH (CK803) || !TARGET_DOUBLE_FLOAT)
>   	    target_fpu_name = "fpv2_sf";
> +	  else if (CSKY_TARGET_ARCH (CK860))
> +	    target_fpu_name = "fpv3";
>   	  else if (TARGET_DOUBLE_FLOAT && TARGET_FDIVDU)
>   	    target_fpu_name = "fpv2_divd";
> +	  else
> +#ifdef CSKY_FPUTYPE_DEFAULT
> +	    target_fpu_name = CSKY_FPUTYPE_DEFAULT;
> +#else
> +	    target_fpu_name = "fpv2";
> +#endif
>   
>   	  ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &fpu_index,
>   				      CL_TARGET);
> @@ -3247,7 +3264,10 @@ decompose_csky_address (rtx addr, struct csky_address *out)
>   	      if (!base)
>   		base = op;
>   	      else if (!index)
> -		index = op;
> +		{
> +		  index = op;
> +		  scale = 1;
> +		}
>   	      else
>   		return false;
>   	      break;
> @@ -3500,6 +3520,14 @@ csky_print_operand (FILE *stream, rtx x, int code)
>   	case UNSPEC:
>   	  csky_output_pic_addr_const (stream, x, code);
>   	  break;
> +	case CONST_DOUBLE:
> +	  {
> +	    char fpstr[20];
> +	    real_to_decimal ( fpstr, CONST_DOUBLE_REAL_VALUE (x),
> +			     sizeof (fpstr), 0, 1);
> +	    fprintf (stream, "%s", fpstr);
> +	  }
> +	  break;
>   	default:
>   	  output_addr_const (stream, x);
>   	  break;
> @@ -4014,12 +4042,26 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	    }
>   
>   	    if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
> -	      return "fmovs\t%0, %1";
> +	      if (CSKY_ISA_FEATURE(fpv2_sf))
> +		return "fmovs\t%0, %1";
> +	      else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		return "fmov.32\t%0, %1";
> +	      else
> +		gcc_unreachable ();
>   	    if (CSKY_VREG_P (dstreg))
> -	      return "fmtvrl\t%0, %1";
> +	      if (CSKY_ISA_FEATURE(fpv2_sf))
> +		return "fmtvrl\t%0, %1";
> +	      else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		return "fmtvr.32.1\t%0, %1";
> +	      else
> +		gcc_unreachable ();
>   	    if (CSKY_VREG_P (srcreg))
> -	      return "fmfvrl\t%0, %1";
> -
> +	      if (CSKY_ISA_FEATURE(fpv2_sf))
> +		return "fmfvrl\t%0, %1";
> +	      else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		return "fmfvr.32.1\t%0, %1";
> +	      else
> +		gcc_unreachable ();
>   	    if (REGNO (src) == CSKY_CC_REGNUM)
>   	      return "mvc\t%0";
>   	    else
> @@ -4040,12 +4082,19 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	      case E_SImode:
>   	      case E_SFmode:
>   		if (CSKY_VREG_P (REGNO (dst)))
> -		  return "fldrs\t%0, %1";
> +		  {
> +		    if (CSKY_ISA_FEATURE(fpv2_sf))
> +		      return "fldrs\t%0, %1";
> +		    else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		      return "fldr.32\t%0, %1";
> +		    else
> +		      gcc_unreachable ();
> +		    }
>   		else
>   		  return "ldr.w\t%0, %1";
> -              case E_V4QImode:
> -              case E_V2HImode:
> -                return "ldr.w\t%0, %1";
> +	      case E_V4QImode:
> +	      case E_V2HImode:
> +		return "ldr.w\t%0, %1";
>   	      default:
>   		gcc_unreachable ();
>   	      }
> @@ -4067,12 +4116,19 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	      case E_SFmode:
>   	      case E_SImode:
>   		if (CSKY_VREG_P (REGNO (dst)))
> -		  return "flds\t%0, %1";
> +		  {
> +		     if (CSKY_ISA_FEATURE(fpv2_sf))
> +		       return "flds\t%0, %1";
> +		     else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		       return "fld.32\t%0, %1";
> +		     else
> +		       gcc_unreachable ();
> +		   }
>   		else
>   		  return "ld.w\t%0, %1";
> -              case E_V4QImode:
> -              case E_V2HImode:
> -                return "ld.w\t%0, %1";
> +	      case E_V4QImode:
> +	      case E_V2HImode:
> +		return "ld.w\t%0, %1";
>   	      default:
>   		gcc_unreachable ();
>   	      }
> @@ -4128,12 +4184,19 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	  case E_SFmode:
>   	  case E_SImode:
>   	    if (CSKY_VREG_P (REGNO (src)))
> -	      return "fstrs\t%1, %0";
> +	      {
> +		if (CSKY_ISA_FEATURE(fpv2_sf))
> +		  return "fstrs\t%1, %0";
> +		else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		  return "fstr.32\t%1, %0";
> +		else
> +		  gcc_unreachable ();
> +	      }
>   	    else
>   	      return "str.w\t%1, %0";
> -          case E_V4QImode:
> -          case E_V2HImode:
> -            return "str.w\t%1, %0";
> +	  case E_V4QImode:
> +	  case E_V2HImode:
> +	    return "str.w\t%1, %0";
>   	  default:
>   	    gcc_unreachable ();
>   	  }
> @@ -4147,12 +4210,19 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
>   	  case E_SImode:
>   	  case E_SFmode:
>   	    if (CSKY_VREG_P (REGNO (src)))
> -	      return "fsts\t%1, %0";
> +	      {
> +		if (CSKY_ISA_FEATURE(fpv2_sf))
> +		  return "fsts\t%1, %0";
> +		else if (CSKY_ISA_FEATURE(fpv3_sf))
> +		  return "fst.32\t%1, %0";
> +		else
> +		  gcc_unreachable ();
> +	      }
>   	    else
>   	      return "st.w\t%1, %0";
> -          case E_V4QImode:
> -          case E_V2HImode:
> -            return "st.w\t%1, %0";
> +	  case E_V4QImode:
> +	  case E_V2HImode:
> +	    return "st.w\t%1, %0";
>   	  default:
>   	    gcc_unreachable ();
>   	  }
> @@ -4289,7 +4359,14 @@ csky_output_movedouble (rtx operands[],
>   		return "mthi\t%R1\n\tmtlo\t%1";
>   	    }
>   	  else if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
> -	    return "fmovd\t%0, %1";
> +	    {
> +	      if (CSKY_ISA_FEATURE(fpv2_df))
> +		return "fmovd\t%0, %1";
> +	      else if (CSKY_ISA_FEATURE(fpv3_df))
> +		return "fmov.64\t%0, %1";
> +	      else
> +		gcc_unreachable ();
> +	    }
>   	  else if (CSKY_VREG_P (srcreg))
>   	    {
>   	      /* Since the vector registers in fpuv2_soft processors
> @@ -4298,18 +4375,46 @@ csky_output_movedouble (rtx operands[],
>   	      if (TARGET_SOFT_FPU)
>   		  return "fmfvrl\t%0, %1";
>   	      else if (TARGET_BIG_ENDIAN)
> -		return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fmfvr.64\t%R0, %0, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	      else
> -		return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fmfvr.64\t%0, %R0, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	    }
>   	  else if (CSKY_VREG_P (dstreg))
>   	    {
>   	      if (TARGET_SOFT_FPU)
>   		return "fmtvrl\t%0, %1";
>   	      else if (TARGET_BIG_ENDIAN)
> -		return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fmtvr.64\t%0, %R1, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	      else
> -		return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fmtvr.64\t%0, %1, %R1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	    }
>   
>   	  /* Ensure the second source not overwritten.  */
> @@ -4351,9 +4456,23 @@ csky_output_movedouble (rtx operands[],
>   	  if (CSKY_VREG_P (dstreg))
>   	    {
>   	      if (op0.index)
> -		return "fldrd\t%0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fldrd\t%0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fldr.64\t%0, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	      else
> -		return "fldd\t%0, %1";
> +		{
> +		  if (CSKY_ISA_FEATURE(fpv2_df))
> +		    return "fldd\t%0, %1";
> +		  else if (CSKY_ISA_FEATURE(fpv3_df))
> +		    return "fld.64\t%0, %1";
> +		  else
> +		    gcc_unreachable ();
> +		}
>   	    }
>   	  /* FIXME length attribute is wrong here.  */
>   	  if (dstreg == basereg)
> @@ -4417,9 +4536,23 @@ csky_output_movedouble (rtx operands[],
>         if (CSKY_VREG_P (srcreg))
>   	{
>   	  if (op0.index)
> -	    return "fstrd\t%1, %0";
> +	    {
> +	      if (CSKY_ISA_FEATURE(fpv2_df))
> +		return "fstrd\t%1, %0";
> +	      else if (CSKY_ISA_FEATURE(fpv3_df))
> +		return "fstr.64\t%1, %0";
> +	      else
> +		gcc_unreachable ();
> +	    }
>   	  else
> -	    return "fstd\t%1, %0";
> +	    {
> +	      if (CSKY_ISA_FEATURE(fpv2_df))
> +		return "fstd\t%1, %0";
> +	      else if (CSKY_ISA_FEATURE(fpv3_df))
> +		return "fst.64\t%1, %0";
> +	      else
> +		gcc_unreachable ();
> +	    }
>   	}
>         /* FIXME length attribute is wrong here.  */
>         if (srcreg == basereg)
> @@ -4546,9 +4679,185 @@ csky_output_ck801_movedouble (rtx operands[],
>       gcc_unreachable ();
>   }
>   
> +/* Calculate the cost of insn for moving double-word data.  */
> +
> +int
> +get_output_csky_movedouble_length(rtx operands[])
> +{
> +  rtx dst = operands[0];
> +  rtx src = operands[1];
> +
> +  if (REG_P (dst))
> +    {
> +      if (REG_P (src))
> +	{
> +	  int dstreg = REGNO (dst);
> +	  int srcreg = REGNO (src);
> +
> +	  if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
> +	    return 4;
> +	  else
> +	    return 8;
> +	}
> +      else if (GET_CODE (src) == MEM)
> +	{
> +	  rtx memexp = XEXP (src, 0);
> +	  int dstreg = REGNO (dst);
> +	  int basereg = -1;
> +	  struct csky_address op0;
> +	  decompose_csky_address (XEXP (src, 0), &op0);
> +
> +	  if (GET_CODE (memexp) == LABEL_REF)
> +	    return 8;
> +	  if (CSKY_VREG_P (dstreg))
> +	    return 4;
> +	  return 8;
> +	}
> +      else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
> +	{
> +	  split_double (src, operands + 2, operands + 3);
> +	  if (CSKY_CONST_OK_FOR_N (INTVAL (operands[2]) + 1)
> +	      && CSKY_CONST_OK_FOR_N (INTVAL (operands[3]) + 1)
> +	      && REGNO (operands[0]) < 6)
> +	    return 4;
> +	  else
> +	    return 8;
> +	}
> +    }
> +  else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
> +    {
> +      rtx memexp = XEXP (dst, 0);
> +      int srcreg = REGNO (src);
> +      int offset = -1;
> +      if (CSKY_VREG_P (srcreg))
> +	return 4;
> +
> +      if (GET_CODE (memexp) == REG)
> +	offset = 0;
> +      else if (GET_CODE (memexp) == PLUS)
> +	{
> +	  if (GET_CODE (XEXP (memexp, 0)) == REG)
> +	    offset = INTVAL (XEXP (memexp, 1));
> +	  else if (GET_CODE (XEXP (memexp, 1)) == REG)
> +	    offset = INTVAL (XEXP (memexp, 0));
> +	  else
> +	    gcc_unreachable ();
> +	}
> +      else
> +	gcc_unreachable ();
> +
> +      if (srcreg <= 6 && offset <= 1020)
> +	return 4;
> +      else if ((srcreg == 7 && offset <= 1024) || (srcreg <= 7 && offset == 1024))
> +	return 6;
> +      else
> +	return 8;
> +    }
> +  else
> +    gcc_unreachable ();
> +}
> +
> +/* Output string for float point load/store instructions
> +   for fpuv3.  */
> +
> +const char *
> +fpuv3_output_move (rtx *operands)
> +{
> +  rtx reg, mem, addr, ops[2];
> +  int load = REG_P (operands[0]);
> +
> +  const char *templ = "f%s%s.%s\t%%0, %%1";
> +  char buff[50];
> +  machine_mode mode;
> +
> +  reg = operands[!load];
> +  mem = operands[load];
> +
> +  gcc_assert (REG_P (reg));
> +  gcc_assert (CSKY_VREG_P (REGNO (reg)));
> +  gcc_assert (MEM_P (mem));
> +
> +  mode = GET_MODE (reg);
> +  const char *type = mode == DFmode ? "64" :
> +		     mode == SFmode ? "32" :
> +		     mode == HFmode ? "16" :
> +		     NULL;
> +  gcc_assert(type != NULL);
> +
> +  addr = XEXP (mem, 0);
> +  struct csky_address caddr;
> +  decompose_csky_address (addr, &caddr);
> +
> +  ops[0] = reg;
> +  ops[1] = mem;
> +  sprintf (buff, templ,
> +	   load ? "ld" : "st",
> +	   caddr.index ? "r" : "",
> +	   type);
> +  output_asm_insn (buff, ops);
> +
> +  return "";
> +}
> +
> +/* Check if a const_double can be used with a VFP fmovi
> +   instruction.  */
> +
> +int
> +fpuv3_const_double_rtx (rtx x)
> +{
> +  REAL_VALUE_TYPE r, m;
> +  r = *CONST_DOUBLE_REAL_VALUE (x);
> +
> +  /* Fpuv3 can't represent these things, so detect them first.  */
> +  if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r) || REAL_VALUE_MINUS_ZERO (r)
> +      || r.cl == rvc_zero)
> +    return 0;
> +
> +  /* Extract sign, exponent and mantissa.  */
> +  int sign, exponent;
> +  sign = REAL_VALUE_NEGATIVE (r) ? 1 : 0;
> +  r = real_value_abs (&r);
> +  exponent = REAL_EXP (&r);
> +
> +  bool fail;
> +  unsigned HOST_WIDE_INT mantissa, mant_hi;
> +  unsigned HOST_WIDE_INT mask;
> +  int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1;
> +  real_ldexp (&m, &r, point_pos - exponent);
> +  wide_int w = real_to_integer (&m, &fail, HOST_BITS_PER_WIDE_INT * 2);
> +  mantissa = w.elt (0);
> +  mant_hi = w.elt (1);
> +
> +  exponent -= 1;
> +
> +  if (!IN_RANGE (exponent, -4, 11))
> +    return 0;
> +
> +  /* If there are bits set in the low part of the mantissa, we can't
> +     represent this value.  */
> +  if (mantissa != 0)
> +    return 0;
> +
> +  /* Now make it so that mantissa contains the most-significant bits, and move
> +     the point_pos to indicate that the least-significant bits have been
> +     discarded.  */
> +  point_pos -= HOST_BITS_PER_WIDE_INT;
> +  mantissa = mant_hi;
> +
> +  /* We can permit 8 significant bits of mantissa only, plus a high bit
> +     which is always 1.  */
> +  mask = ((unsigned HOST_WIDE_INT)1 << (point_pos - 9)) - 1;
> +  if ((mantissa & mask) != 0)
> +    return 0;
> +
> +  return 1;
> +}
> +
> +
>   /* Split operands for an AND expression when OPERANDS[2] is a constant.
>      Note operands[0] is marked earlyclobber in this case and can be
>      overwritten.  Return true if "DONE", false otherwise.  */
> +
>   bool
>   csky_split_and (rtx *operands)
>   {
> @@ -4678,6 +4987,7 @@ csky_split_and (rtx *operands)
>   /* Split operands for an IOR expression when OPERANDS[2] is a constant.
>      Note operands[0] is marked earlyclobber in this case and can be
>      overwritten.  Return true if "DONE", false otherwise.  */
> +
>   bool
>   csky_split_ior (rtx *operands)
>   {
> @@ -4745,6 +5055,7 @@ csky_split_ior (rtx *operands)
>   /* Split operands for an XOR expression when OPERANDS[2] is a constant.
>      Note operands[0] is marked earlyclobber in this case and can be
>      overwritten.  Return true if "DONE", false otherwise.  */
> +
>   bool
>   csky_split_xor (rtx *operands)
>   {
> @@ -4793,6 +5104,7 @@ csky_split_xor (rtx *operands)
>   
>   
>   /* Return true if X is an address form involving a symbol or label ref.  */
> +
>   bool
>   csky_symbolic_address_p (rtx x)
>   {
> @@ -4821,6 +5133,9 @@ csky_emit_compare (enum rtx_code code, rtx op0, rtx op1)
>     bool invert;
>     rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
>   
> +  if (GET_MODE_CLASS(GET_MODE (op0)) == MODE_FLOAT)
> +    return csky_emit_compare_float(code, op0, op1);
> +
>     if (GET_CODE (op1) == CONST_INT)
>       {
>         HOST_WIDE_INT val = INTVAL (op1);
> @@ -5735,6 +6050,7 @@ tls_unspec_mentioned_p (rtx x)
>   
>   
>   /* Implement LEGITIMATE_PIC_OPERAND_P.  */
> +
>   bool
>   csky_legitimate_pic_operand_p (rtx x)
>   {
> @@ -5965,33 +6281,20 @@ csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
>       op1 = force_reg (mode, op1);
>   
>     invert = false;
> +
>     switch (code)
>       {
>       case EQ:
>         code = NE;
>         invert = true;
>         break;
> -
> -    case NE:
> -      break;
> -    case LE:
> -      if (op1 == CONST0_RTX (mode))
> -	op1 = force_reg (mode, op1);
> -      break;
>       case GT:
> -      if (op1 == CONST0_RTX (mode))
> -	op1 = force_reg (mode, op1);
> -      break;
> -    case GE:
> -      break;
>       case LT:
> -      if (op1 == CONST0_RTX (mode))
> -	{
> -	  code = GE;
> -	  invert = true;
> -	}
> -      break;
> -    case UNORDERED:
> +    case LE:
> +      if (op1 == CONST0_RTX (mode) && (CSKY_ISA_FEATURE_GET(fpv2_sf)
> +				       || CSKY_ISA_FEATURE_GET(fpv2_df)
> +				       || CSKY_ISA_FEATURE_GET(fpv2_divd)))
> +	op1 = force_reg (mode, op1);
>         break;
>       case ORDERED:
>         code = UNORDERED;
> @@ -6007,10 +6310,11 @@ csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
>     return invert;
>   }
>   
> -/* Support for the Q memory constraint.  Returns true if OP is a MEM RTX
> -   with an address consisting of base + index or base + displacement.  */
> +/* Support for the Q or W memory constraint.  Returns true if OP is a MEM
> +   RTX with an address consisting of base + index or base + displacement.  */
> +
>   bool
> -csky_valid_fpuv2_mem_operand (rtx op)
> +csky_valid_mem_constraint_operand (rtx op, const char *constraint)
>   {
>     struct csky_address addr;
>   
> @@ -6025,7 +6329,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
>       return false;
>   
>     /* Verify index operand. */
> -  if (addr.index)
> +  if (addr.index && (constraint[0] == 'Q' || constraint[0] == 'W'))
>       {
>         if (!is_csky_address_register_rtx_p (addr.index, 0))
>   	return false;
> @@ -6037,7 +6341,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
>         return false;
>       }
>     /* Verify disp operand.  */
> -  else if (addr.disp)
> +  else if (addr.disp && constraint[0] == 'Q')
>       {
>         rtx disp = addr.disp;
>   
> @@ -6469,7 +6773,7 @@ ck803_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
>       }
>   }
>   
> -/* TARGET_RTX_COSTS helper for ck807+ arches.  */
> +/* TARGET_RTX_COSTS helper for ck807/ck810 arches.  */
>   
>   static bool
>   ck807_ck810_rtx_costs (rtx x, int code,
> @@ -6500,6 +6804,52 @@ ck807_ck810_rtx_costs (rtx x, int code,
>       }
>   }
>   
> +/* TARGET_RTX_COSTS helper for ck860 arches.  */
> +
> +static bool
> +ck860_rtx_costs (rtx x, int code, machine_mode mode,
> +		 int outer_code ATTRIBUTE_UNUSED,
> +		 int *total, bool speed ATTRIBUTE_UNUSED)
> +{
> +  switch (code)
> +    {
> +    case PLUS:
> +      /* The costs of mula is 1 more than mult.  */
> +      if (GET_CODE (XEXP (x, 0)) == MULT && REG_P (XEXP (x, 1)) && speed)
> +	{
> +	  rtx mul_op0 = XEXP (XEXP (x, 0), 0);
> +	  rtx mul_op1 = XEXP (XEXP (x, 0), 1);
> +	  if (REG_P (mul_op0) && REG_P (mul_op1))
> +	    {
> +	      *total = COSTS_N_INSNS (1);
> +	      *total += rtx_cost (XEXP (x, 0), mode,
> +				  (enum rtx_code) code, 0, speed);
> +	      return true;
> +	    }
> +	}
> +      return false;
> +    case MULT:
> +      if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
> +	{
> +	  HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
> +	  if (val % 2 == 0 && val < 0xffffffff && val > 0)
> +	    {
> +	      *total = COSTS_N_INSNS (1);
> +	      return true;
> +	    }
> +	}
> +      return false;
> +
> +    case CONST:
> +    case LABEL_REF:
> +    case SYMBOL_REF:
> +      *total = COSTS_N_INSNS (3);
> +      return true;
> +    default:
> +      return false;
> +    }
> +}
> +
>   
>   /* Implement TARGET_RTX_COSTS, to compute a (partial) cost for rtx X.
>      Return true if the complete cost has been computed, and false if
> @@ -6518,6 +6868,8 @@ csky_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
>       return ck803_rtx_costs (x, code, outer_code, total, speed);
>     else if (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
>       return ck807_ck810_rtx_costs (x, code, outer_code, total, speed);
> +  else if (CSKY_TARGET_ARCH (CK860))
> +    return ck860_rtx_costs (x, code, mode, outer_code, total, speed);
>     else
>       gcc_unreachable ();
>   }
> @@ -6660,6 +7012,7 @@ csky_warn_func_return (tree decl)
>   /* Implement TARGET_RETURN_IN_MEMORY to decide whether TYPE should be
>      returned in memory (true) or in a register (false).
>      FNTYPE is the type of the function making the call.  */
> +
>   static bool
>   csky_return_in_memory (const_tree type,
>   		       const_tree fntype ATTRIBUTE_UNUSED)
> @@ -6673,6 +7026,7 @@ csky_return_in_memory (const_tree type,
>      Dwarf models VFP registers as  64-bit or 128-bit registers default.
>      GCC models tham as 32-bit registers, so we need to describe this to
>      the DWARF generation code.  Other registers can use the default.  */
> +
>   static rtx
>   csky_dwarf_register_span (rtx rtl)
>   {
> @@ -6866,8 +7220,8 @@ csky_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
>   
>   void
>   csky_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
> -                           rtx libname ATTRIBUTE_UNUSED,
> -                           tree fndecl ATTRIBUTE_UNUSED)
> +			   rtx libname ATTRIBUTE_UNUSED,
> +			   tree fndecl ATTRIBUTE_UNUSED)
>   {
>     memset(pcum, 0, sizeof(*pcum));
>     if (stdarg_p (fntype))
> @@ -6882,7 +7236,7 @@ csky_vector_mode_supported_p (machine_mode mode)
>   {
>     if (CSKY_ISA_FEATURE (dsp2)
>         && (mode == V4QImode || mode == V2HImode
> -          || mode == V2SImode || mode == V4HImode))
> +	  || mode == V2SImode || mode == V4HImode))
>       return true;
>   
>     return false;
> @@ -6897,14 +7251,14 @@ csky_preferred_simd_mode (scalar_mode mode)
>     if (CSKY_ISA_FEATURE (dsp2))
>       {
>         switch (mode)
> -        {
> -        case E_QImode:
> -          return V4QImode;
> -        case E_HImode:
> -          return V2HImode;
> -        default:
> -          break;
> -        }
> +	{
> +	case E_QImode:
> +	  return V4QImode;
> +	case E_HImode:
> +	  return V2HImode;
> +	default:
> +	  break;
> +	}
>       }
>     return word_mode;
>   }
> diff --git a/gcc/config/csky/csky.h b/gcc/config/csky/csky.h
> index 5abdeda3e67..a4c76ec7a38 100644
> --- a/gcc/config/csky/csky.h
> +++ b/gcc/config/csky/csky.h
> @@ -124,7 +124,7 @@
>     (optimize_size && TARGET_CONSTANT_POOL \
>      && (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802)))
>   #define TARGET_TLS \
> -  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
> +  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK860))
>   
>   /* Run-time Target Specification.  */
>   #define TARGET_SOFT_FLOAT       (csky_float_abi == CSKY_FLOAT_ABI_SOFT)
> diff --git a/gcc/config/csky/csky.md b/gcc/config/csky/csky.md
> index a4f3d284812..e99ab799e9c 100644
> --- a/gcc/config/csky/csky.md
> +++ b/gcc/config/csky/csky.md
> @@ -425,85 +425,6 @@
>      (set_attr "type" "alu,alu,alu,load,load,store")]
>   )
>   
> -;; Float mov instructions.
> -
> -(define_expand "movsf"
> -  [(set (match_operand:SF 0 "general_operand" "")
> -	(match_operand:SF 1 "general_operand" ""))]
> -  ""
> -  "
> -  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
> -    operands[1] = force_reg (SFmode, operands[1]);
> -  "
> -)
> -
> -;; FIXME: maybe the vreg load/stores should have their own type attr.
> -(define_insn "*csky_movsf_fpv2"
> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v")
> -	(match_operand:SF 1 "general_operand"	   " b,r,r,v,m,mF,r,v,Q,v,m"))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "* return csky_output_move (insn, operands, SFmode);"
> -  [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4")
> -   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
> -)
> -
> -(define_insn "*ck801_movsf"
> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
> -	(match_operand:SF 1 "general_operand"	   " r,m,mF,r"))]
> -  "CSKY_ISA_FEATURE (E1)"
> -  "* return csky_output_ck801_move (insn, operands, SFmode);"
> -  [(set_attr "length" "2,4,4,4")
> -   (set_attr "type" "alu,load,load,store")]
> -)
> -
> -(define_insn "*csky_movsf"
> -  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
> -	(match_operand:SF 1 "general_operand"	   " b,r,m,mF,r"))]
> -  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_sf)"
> -  "* return csky_output_move (insn, operands, SFmode);"
> - [(set_attr "length" "2,4,4,4,4")
> -  (set_attr "type" "alu,alu,load,load,store")]
> -)
> -
> -
> -(define_expand "movdf"
> -  [(set (match_operand:DF 0 "general_operand" "")
> -	(match_operand:DF 1 "general_operand" ""))]
> -  ""
> -  "
> -  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
> -      operands[1] = force_reg (DFmode, operands[1]);
> -  "
> -)
> -
> -;; FIXME: maybe the vreg load/stores should have their own type attr.
> -(define_insn "*csky_movdf_fpv2"
> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v")
> -	(match_operand:DF 1 "general_operand"	    "b,r,r,v,m,mF,r,v,Q,v,m"))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "* return csky_output_movedouble (operands, DFmode);"
> -  [(set_attr "length" "4,8,8,8,8,8,8,8,8,8,8")
> -   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
> -)
> -
> -(define_insn "*ck801_movdf"
> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
> -	(match_operand:DF 1 "general_operand"	   " r,m,mF,r"))]
> -  "CSKY_ISA_FEATURE (E1)"
> -  "* return csky_output_ck801_movedouble (operands, DFmode);"
> -  [(set_attr "length" "4,8,8,8")
> -   (set_attr "type" "alu,load,load,store")]
> -)
> -
> -(define_insn "*csky_movdf"
> -  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
> -	(match_operand:DF 1 "general_operand"	   " b,r,m,mF,r"))]
> -  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_df)"
> -  "* return csky_output_movedouble (operands, DFmode);"
> - [(set_attr "length" "4,8,8,8,8")
> -  (set_attr "type" "alu,alu,load,load,store")]
> -)
> -
>   ;; The only CCmode move supported is a nop.  Without this pattern,
>   ;; CSE is unable to eliminate redundant comparisons in conditional
>   ;; execution expressions.
> @@ -524,7 +445,7 @@
>   
>   (define_expand "movsicc"
>     [(set (match_operand 0 "register_operand" "")
> -	(if_then_else:SI (match_operand	   1 "ordered_comparison_operator" "")
> +	(if_then_else:SI (match_operand	   1 "comparison_operator" "")
>   			 (match_operand:SI 2 "register_operand" "")
>   			 (match_operand:SI 3 "register_operand" "")))]
>     "CSKY_ISA_FEATURE (E2)"
> @@ -916,7 +837,7 @@
>     if (CSKY_ISA_FEATURE (E1) && (GET_CODE (operands[2]) != REG))
>         operands[2] = force_reg (DImode, operands[2]);
>     else if (CSKY_ISA_FEATURE (dsp2) && (REG_P (operands[2])
> -                                       || SUBREG_P (operands[2])))
> +				       || SUBREG_P (operands[2])))
>       {
>         emit_insn (gen_dsp2_adddi3 (operands[0], operands[1], operands[2]));
>         DONE;
> @@ -1335,7 +1256,7 @@
>   
>   (define_expand "addsicc"
>     [(match_operand:SI 0 "register_operand" "")
> -   (match_operand    1 "ordered_comparison_operator" "")
> +   (match_operand    1 "comparison_operator" "")
>      (match_operand:SI 2 "register_operand" "")
>      (match_operand:SI 3 "csky_literal_K_Uh_operand" "")]
>     "CSKY_ISA_FEATURE (E2)"
> @@ -3330,9 +3251,9 @@
>   
>   (define_expand "untyped_call"
>     [(parallel [(call (match_operand 0 "" "")
> -        (const_int 0))
> -        (match_operand 1 "" "")
> -        (match_operand 2 "" "")])]
> +	(const_int 0))
> +	(match_operand 1 "" "")
> +	(match_operand 2 "" "")])]
>     ""
>   {
>     int i;
> @@ -3364,9 +3285,9 @@
>     [(set_attr "length" "0")])
>   
>   (define_insn "*call_value_internal_vs"
> -  [(set (match_operand:SF               0 "register_operand"          "=v,v,v")
> -        (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
> -              (match_operand 2 "" "")))
> +  [(set (match_operand:SF	       0 "register_operand"	  "=v,v,v")
> +	(call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
> +	      (match_operand 2 "" "")))
>      (clobber (reg:SI CSKY_LR_REGNUM))]
>     "TARGET_HARD_FLOAT_ABI"
>     "@
> @@ -3378,9 +3299,9 @@
>   )
>   
>   (define_insn "*call_value_internal_vd"
> -  [(set (match_operand:DF               0 "register_operand"          "=v,v,v")
> -        (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
> -              (match_operand 2 "" "")))
> +  [(set (match_operand:DF	       0 "register_operand"	  "=v,v,v")
> +	(call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
> +	      (match_operand 2 "" "")))
>      (clobber (reg:SI CSKY_LR_REGNUM))]
>     "TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
>     "@
> @@ -3392,18 +3313,18 @@
>   )
>   
>   (define_insn "*call_value_internal_pic_vs"
> -  [(set (match_operand:SF               0 "register_operand"    "=v")
> -        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
> -                      (match_operand    2 "" "")))
> +  [(set (match_operand:SF	       0 "register_operand"    "=v")
> +	(call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
> +		      (match_operand    2 "" "")))
>      (clobber (reg:SI CSKY_LR_REGNUM))]
>     "flag_pic && TARGET_HARD_FLOAT_ABI"
>     "* return csky_output_call (operands, 1);"
>   )
>   
>   (define_insn "*call_value_internal_pic_vd"
> -  [(set (match_operand:DF               0 "register_operand"    "=v")
> -        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
> -                      (match_operand    2 "" "")))
> +  [(set (match_operand:DF	       0 "register_operand"    "=v")
> +	(call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
> +		      (match_operand    2 "" "")))
>      (clobber (reg:SI CSKY_LR_REGNUM))]
>     "flag_pic && TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
>     "* return csky_output_call (operands, 1);"
> @@ -3894,8 +3815,3 @@
>     "CSKY_ISA_FEATURE (E2)"
>     "revb\t%0, %1"
>   )
> -
> -
> -
> -
> -
> diff --git a/gcc/config/csky/csky_cores.def b/gcc/config/csky/csky_cores.def
> index c18fa795051..909c737dd74 100644
> --- a/gcc/config/csky/csky_cores.def
> +++ b/gcc/config/csky/csky_cores.def
> @@ -38,6 +38,8 @@ CSKY_ARCH ("ck807",  ck807,  CK807,
>   	   CSKY_ISA_FEAT (CSKY_ISA_CK807) CSKY_ISA_FEAT (CSKY_ISA_DSP))
>   CSKY_ARCH ("ck810",  ck810,  CK810,
>   	   CSKY_ISA_FEAT (CSKY_ISA_CK810) CSKY_ISA_FEAT (CSKY_ISA_DSP))
> +CSKY_ARCH ("ck860",  ck860,  CK860,
> +	   CSKY_ISA_FEAT (CSKY_ISA_CK860))
>   #endif
>   
>   
> @@ -181,6 +183,12 @@ CSKY_CORE ("ck810ft",  ck810ff,	 ck810ft,  CK810,
>   	   CSKY_ISA_FEAT_NONE)
>   CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
>   	   CSKY_ISA_FEAT_NONE)
> +
> +/* ck860 Architecture Processors */
> +CSKY_CORE("ck860",    ck860,    ck860,    CK860,
> +	  CSKY_ISA_FEAT_NONE)
> +CSKY_CORE("ck860f",   ck860f,   ck860f,   CK860,
> +	  CSKY_ISA_FEAT_NONE)
>   #endif
>   
>   
> @@ -196,4 +204,9 @@ CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
>   CSKY_FPU ("fpv2_sf",   fpv2_sf,	  CSKY_ISA_FEAT (CSKY_ISA_FPv2_SF))
>   CSKY_FPU ("fpv2",      fpv2,	  CSKY_ISA_FEAT (CSKY_ISA_FPv2))
>   CSKY_FPU ("fpv2_divd", fpv2_divd, CSKY_ISA_FEAT (CSKY_ISA_FPv2_DIVD))
> +
> +CSKY_FPU ("fpv3_hf",   fpv3_hf,   CSKY_ISA_FEAT (CSKY_ISA_FPv3_HF))
> +CSKY_FPU ("fpv3_hsf",  fpv3_hsf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_HSF))
> +CSKY_FPU ("fpv3_sdf",  fpv3_sdf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_SDF))
> +CSKY_FPU ("fpv3",      fpv3,      CSKY_ISA_FEAT (CSKY_ISA_FPv3))
>   #endif
> diff --git a/gcc/config/csky/csky_insn_fpu.md b/gcc/config/csky/csky_insn_fpu.md
> index 700208ebe93..d829b426ab7 100644
> --- a/gcc/config/csky/csky_insn_fpu.md
> +++ b/gcc/config/csky/csky_insn_fpu.md
> @@ -18,528 +18,313 @@
>   ;; along with GCC; see the file COPYING3.  If not see
>   ;; <http://www.gnu.org/licenses/>.  */
>   
> -;; -------------------------------------------------------------------------
> -;; Float Abs instructions
> -;; -------------------------------------------------------------------------
> +(define_c_enum "unspec" [
> +  UNSPEC_FLOOR
> +  UNSPEC_CEIL
> +  UNSPEC_BTRUNC
> +  UNSPEC_RINT
> +])
>   
> -(define_insn "abssf2"
> -  [(set (match_operand:SF	  0 "register_operand" "=v,r")
> -	(abs:SF (match_operand:SF 1 "register_operand" "v, r")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "@
> -    fabss\t%0, %1
> -    bclri\t%0, %1, 31")
> +(define_c_enum "unspecv" [
> +  VUNSPEC_GET_FCR     ; Represent fetch of FCR content.
> +  VUNSPEC_SET_FCR     ; Represent assign of FCR content.
> +  VUNSPEC_INS_FCR     ; Represent insert of FCR content.
> +])
>   
> -(define_insn "absdf2"
> -  [(set (match_operand:DF	  0 "register_operand" "=v")
> -	(abs:DF (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fabsd\t%0, %1")
> +(define_mode_iterator F3ANY [HF SF DF])
> +(define_mode_attr f3t [(HF "16") (SF "32") (DF "64")])
>   
> +(define_mode_iterator SFDF [SF DF])
> +(define_mode_attr f2t [(SF "32") (DF "64")])
>   
> -;; -------------------------------------------------------------------------
> -;; Float Neg instructions
> -;; -------------------------------------------------------------------------
> +(define_code_iterator FCMPZ [ne ge lt gt le])
> +(define_code_attr zero_inst [(ne "nez") (ge "hsz") (lt "ltz") (gt "hz") (le "lsz")])
>   
> -(define_insn "negsf2"
> -  [(set (match_operand:SF	  0 "register_operand" "=v")
> -	(neg:SF (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnegs\t%0, %1")
> +(define_code_iterator FCMP [ne ge lt])
> +(define_code_attr reg_inst [(ne "ne") (ge "hs") (lt "lt")])
>   
> -(define_insn "negdf2"
> -  [(set (match_operand:DF	  0 "register_operand" "=v")
> -	(neg:DF (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnegd\t%0, %1")
> +(define_code_iterator FIX_SU [fix unsigned_fix])
> +(define_code_attr fixsuop [(fix "")  (unsigned_fix "uns")])
> +(define_code_attr fixsu   [(fix "s") (unsigned_fix "u")])
>   
> +(define_code_iterator FLOAT_SU [float unsigned_float])
> +(define_code_attr floatsuop [(float "")  (unsigned_float "uns")])
> +(define_code_attr floatsu   [(float "s") (unsigned_float "u")])
>   
> -;; -------------------------------------------------------------------------
> -;; Float Sqrt instructions
> -;; -------------------------------------------------------------------------
> +(define_int_iterator FRM  [UNSPEC_FLOOR
> +			   UNSPEC_CEIL UNSPEC_RINT])
>   
> -(define_insn "sqrtsf2"
> -  [(set (match_operand:SF	   0 "register_operand" "=v")
> -	(sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fsqrts\t%0, %1")
> +(define_int_iterator FRMF [UNSPEC_FLOOR
> +			   UNSPEC_CEIL UNSPEC_BTRUNC])
>   
> -(define_insn "sqrtdf2"
> -  [(set (match_operand:DF	   0 "register_operand" "=v")
> -	(sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_divd)"
> - "fsqrtd\t%0, %1")
> +(define_int_attr frm_pattern [(UNSPEC_FLOOR "floor")
> +			      (UNSPEC_CEIL "ceil")   (UNSPEC_BTRUNC "btrunc")
> +			      (UNSPEC_RINT "rint")])
> +
> +(define_int_attr rm [(UNSPEC_FLOOR ".rni")
> +		     (UNSPEC_CEIL ".rpi")  (UNSPEC_BTRUNC ".rz")
> +		     (UNSPEC_RINT "")])
>   
>   
>   ;; -------------------------------------------------------------------------
> -;; Float Add instructions
> +;; Float mov instructions
>   ;; -------------------------------------------------------------------------
>   
> -(define_insn "addsf3"
> -  [(set (match_operand:SF	   0 "register_operand" "=v")
> -	(plus:SF (match_operand:SF 1 "register_operand" "v")
> -		 (match_operand:SF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fadds\t%0, %1, %2")
> +(define_expand "movhf"
> +  [(set (match_operand:HF 0 "general_operand" "")
> +	(match_operand:HF 1 "general_operand" ""))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "
> +  {
> +    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
> +      {
> +	operands[1] = force_reg (HFmode, operands[1]);
> +      }
> +  }
> +")
> +
> +(define_expand "mov<mode>"
> +  [(set (match_operand:SFDF 0 "general_operand" "")
> +	(match_operand:SFDF 1 "general_operand" ""))]
> +  ""
> +  "
> +  {
> +    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
> +      {
> +	operands[1] = force_reg (<MODE>mode, operands[1]);
> +      }
> +  }
> +")
> +
> +;; Move float value with general register.
> +
> +(define_insn "*e2_movsf"
> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
> +       (match_operand:SF 1 "general_operand"      " b,r,m,mF,r"))]
> +  "CSKY_ISA_FEATURE (E2)
> +   && !CSKY_ISA_FEATURE (fpv2_sf)
> +   && !CSKY_ISA_FEATURE (fpv3_sf)"
> +  "* return csky_output_move (insn, operands, SFmode);"
> + [(set_attr "length" "2,4,4,4,4")
> +  (set_attr "type" "alu,alu,load,load,store")]
> +)
> +
> +(define_insn "*e2_movdf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
> +       (match_operand:DF 1 "general_operand"      " b,r,m,mF,r"))]
> +  "CSKY_ISA_FEATURE (E2)
> +   && !CSKY_ISA_FEATURE (fpv2_df)
> +   && !CSKY_ISA_FEATURE (fpv3_df)"
> +  "* return csky_output_movedouble (operands, DFmode);"
> + [(set_attr "length" "4,8,8,8,8")
> +  (set_attr "type" "alu,alu,load,load,store")]
> +)
>   
> -(define_insn "adddf3"
> -  [(set (match_operand:DF	   0 "register_operand" "=v")
> -	(plus:DF (match_operand:DF 1 "register_operand" "v")
> -		 (match_operand:DF 2 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_df)"
> - "faddd\t%0, %1, %2")
> +(define_insn "*e1_movsf"
> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
> +	(match_operand:SF 1 "general_operand"      " r,m,mF,r"))]
> +  "CSKY_ISA_FEATURE (E1)"
> +  "* return csky_output_ck801_move (insn, operands, SFmode);"
> +  [(set_attr "length" "2,4,4,4")
> +   (set_attr "type" "alu,load,load,store")]
> +)
>   
> +(define_insn "*e1_movdf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
> +	(match_operand:DF 1 "general_operand"      " r,m,mF,r"))]
> +  "CSKY_ISA_FEATURE (E1)"
> +  "* return csky_output_ck801_movedouble (operands, DFmode);"
> +  [(set_attr "length" "4,8,8,8")
> +   (set_attr "type" "alu,load,load,store")]
> +)
>   
>   ;; -------------------------------------------------------------------------
> -;; Float Sub instructions
> +;; Float Mul instructions
>   ;; -------------------------------------------------------------------------
>   
> -(define_insn "subsf3"
> -  [(set (match_operand:SF	    0 "register_operand" "=v")
> -	(minus:SF (match_operand:SF 1 "register_operand" "v")
> -		  (match_operand:SF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fsubs\t%0, %1, %2")
> +(define_expand "mulhf3"
> +  [(set (match_operand:HF	    0 "register_operand" "=v")
> +	(mult:HF (match_operand:HF   1 "register_operand" "v")
> +		 (match_operand:HF   2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
>   
> -(define_insn "subdf3"
> -  [(set (match_operand:DF	    0 "register_operand" "=v")
> -	(minus:DF (match_operand:DF 1 "register_operand" "v")
> -		  (match_operand:DF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fsubd\t%0, %1, %2")
> +(define_expand "mul<mode>3"
> +  [(set (match_operand:SFDF	    0 "register_operand" "=v")
> +	(mult:SFDF (match_operand:SFDF   1 "register_operand" "v")
> +		 (match_operand:SFDF   2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>)
> +  || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
>   
> +(define_expand "fma<mode>4"
> +  [(set (match_operand:F3ANY	    0 "register_operand" "=v")
> +	(fma:F3ANY (match_operand:F3ANY  1 "register_operand" "v")
> +		   (match_operand:F3ANY  2 "register_operand" "v")
> +		   (match_operand:F3ANY  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
>   
>   ;; -------------------------------------------------------------------------
> -;; Float Mul instructions
> +;; Float ADD SUB NEG ABS instructions
>   ;; -------------------------------------------------------------------------
>   
> -(define_insn "mulsf3"
> -  [(set (match_operand:SF	   0 "register_operand" "=v")
> -	(mult:SF (match_operand:SF 1 "register_operand" "v")
> -		 (match_operand:SF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fmuls\t%0, %1, %2")
> -
> -(define_insn "muldf3"
> -  [(set (match_operand:DF	   0 "register_operand" "=v")
> -	(mult:DF (match_operand:DF 1 "register_operand" "v")
> -		 (match_operand:DF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fmuld\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_nmulsf3_1"
> -  [(set (match_operand:SF		   0 "register_operand" "=v")
> -	(mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
> -		 (match_operand:SF	   2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
> -  "fnmuls\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_nmulsf3_2"
> -  [(set (match_operand:SF		   0 "register_operand" "=v")
> -	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> -			 (match_operand:SF 2 "register_operand" "v"))))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnmuls\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_nmuldf3_1"
> -  [(set (match_operand:DF		   0 "register_operand" "=v")
> -	(mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
> -		 (match_operand:DF	   2 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
> - "fnmuld\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_nmuldf3_2"
> -  [(set (match_operand:DF		   0 "register_operand" "=v")
> -	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> -			 (match_operand:DF 2 "register_operand" "v"))))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnmuld\t%0, %1, %2")
> +(define_expand "addhf3"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(plus:HF (match_operand:HF  1 "register_operand" "")
> +		 (match_operand:HF  2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
>   
> +(define_expand "add<mode>3"
> +  [(set (match_operand:SFDF	     0 "register_operand" "")
> +	(plus:SFDF (match_operand:SFDF  1 "register_operand" "")
> +		   (match_operand:SFDF  2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
> -;; -------------------------------------------------------------------------
> -;; Float Div instructions
> -;; -------------------------------------------------------------------------
> +(define_expand "subhf3"
> +  [(set (match_operand:HF	    0 "register_operand" "")
> +	(minus:HF (match_operand:HF  1 "register_operand" "")
> +		  (match_operand:HF  2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
>   
> -(define_expand "divsf3"
> -  [(set (match_operand:SF	  0 "register_operand" "")
> -	(div:SF (match_operand:SF 1 "csky_arith_float1_operand" "")
> -		(match_operand:SF 2 "register_operand" "")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "")
> +(define_expand "sub<mode>3"
> +  [(set (match_operand:SFDF	      0 "register_operand" "")
> +	(minus:SFDF (match_operand:SFDF  1 "register_operand" "")
> +		    (match_operand:SFDF  2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
> -(define_insn "*fpuv2_divsf3"
> -  [(set (match_operand:SF	  0 "register_operand" "=v")
> -	(div:SF (match_operand:SF 1 "register_operand" "v")
> -		(match_operand:SF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fdivs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_1_divsf3"
> -  [(set (match_operand:SF	  0 "register_operand"		"=v")
> -	(div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
> -		(match_operand:SF 2 "register_operand"		"v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "frecips\t%0, %2")
> -
> -
> -(define_expand "divdf3"
> -  [(set (match_operand:DF 0 "register_operand" "")
> -	(div:DF (match_operand:DF 1 "csky_arith_float1_operand" "")
> -		(match_operand:DF 2 "register_operand" "")))]
> -  "CSKY_ISA_FEATURE (fpv2_divd)"
> -  "")
> +(define_expand "abshf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(abs:HF (match_operand:HF   1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
> +
> +(define_expand "abs<mode>2"
> +  [(set (match_operand:SFDF	     0 "register_operand" "")
> +	(abs:SFDF (match_operand:SFDF   1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
> +
> +(define_expand "neghf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(neg:HF (match_operand:HF   1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
>   
> -(define_insn "*fpuv2_divdf3"
> -  [(set (match_operand:DF	  0 "register_operand" "=v")
> -	(div:DF (match_operand:DF 1 "register_operand" "v")
> -		(match_operand:DF 2 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_divd)"
> -  "fdivd\t%0, %1, %2")
> +(define_expand "neg<mode>2"
> +  [(set (match_operand:SFDF	   0 "register_operand" "")
> +	(neg:SFDF (match_operand:SFDF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
> -(define_insn "*fpuv2_1_divdf3"
> -  [(set (match_operand:DF	  0 "register_operand"		"=v")
> -	(div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
> -		(match_operand:DF 2 "register_operand"		"v")))]
> -  "CSKY_ISA_FEATURE (fpv2_divd)"
> -  "frecipd\t%0, %2")
> +(define_expand "sqrthf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(sqrt:HF (match_operand:HF  1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  ""
> +)
>   
> +(define_expand "sqrt<mode>2"
> +  [(set (match_operand:SFDF	    0 "register_operand" "")
> +	(sqrt:SFDF (match_operand:SFDF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  ""
> +)
>   
>   ;; -------------------------------------------------------------------------
> -;; Float add(sub) with mult instructions
> +;; Float div instructions
>   ;; -------------------------------------------------------------------------
>   
> -;; vrz <= vrz + vrx * vry
> -(define_insn "*fpuv2_fmacs"
> -  [(set (match_operand:SF		    0 "register_operand" "=v")
> -	(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> -			  (match_operand:SF 2 "register_operand" "v"))
> -		 (match_operand:SF	    3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fmacs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fmacd"
> -  [(set (match_operand:DF		    0 "register_operand" "=v")
> -	(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> -			  (match_operand:DF 2 "register_operand" "v"))
> -		 (match_operand:DF	    3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fmacd\t%0, %1, %2")
> -
> -;; vrz <= vrz - vrx * vry
> -(define_insn "*fpuv2_fnmacs"
> -  [(set (match_operand:SF		     0 "register_operand" "=v")
> -	(minus:SF (match_operand:SF	     1 "register_operand" "0")
> -		  (mult:SF (match_operand:SF 2 "register_operand" "v")
> -			   (match_operand:SF 3 "register_operand" "v"))))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnmacs\t%0, %2, %3")
> -
> -(define_insn "*fpuv2_fnmacd"
> -  [(set (match_operand:DF		     0 "register_operand" "=v")
> -	(minus:DF (match_operand:DF	     1 "register_operand" "0")
> -		  (mult:DF (match_operand:DF 2 "register_operand" "v")
> -			   (match_operand:DF 3 "register_operand" "v"))))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnmacd\t%0, %2, %3")
> -
> -;; vrz <= vrx * vry - vrz
> -(define_insn "*fpuv2_fmscs"
> -  [(set (match_operand:SF		     0 "register_operand" "=v")
> -	(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> -			   (match_operand:SF 2 "register_operand" "v"))
> -		  (match_operand:SF	     3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fmscs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fmscd"
> -  [(set (match_operand:DF 0 "register_operand" "=v")
> -	(minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> -			   (match_operand:DF 2 "register_operand" "v"))
> -		  (match_operand:DF 3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fmscd\t%0, %1, %2")
> -
> -;; vrz = - (vrz + vrx * vry)
> -(define_insn "*fpuv2_fnmscs_1"
> -  [(set (match_operand:SF			     0 "register_operand" "=v")
> -	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
> -			   (match_operand:SF	     2 "register_operand" "v"))
> -		  (match_operand:SF		     3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnmscs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fnmscs_2"
> -  [(set (match_operand:SF			    0 "register_operand" "=v")
> -	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> -				  (match_operand:SF 2 "register_operand" "v"))
> -			 (match_operand:SF	    3 "register_operand" "0"))))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fnmscs\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fnmscd_1"
> -  [(set (match_operand:DF 0 "register_operand" "=v")
> -	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
> -			   (match_operand:DF 2 "register_operand" "v"))
> -		  (match_operand:DF 3 "register_operand" "0")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnmscd\t%0, %1, %2")
> -
> -(define_insn "*fpuv2_fnmscd_2"
> -  [(set (match_operand:DF 0 "register_operand" "=v")
> -	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> -				  (match_operand:DF 2 "register_operand" "v"))
> -			 (match_operand:DF 3 "register_operand" "0"))))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fnmscd\t%0, %1, %2")
> +(define_expand "div<mode>3"
> +  [(set (match_operand:SFDF	   0 "register_operand" "")
> +	(div:SFDF (match_operand:SFDF 1 "csky_arith_float1_operand" "")
> +		  (match_operand:SFDF 2 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
>   
> +(define_expand "divhf3"
> + [(set (match_operand:HF 0 "register_operand" "")
> +       (div:HF (match_operand:HF 1 "csky_arith_float1_operand" "")
> +	       (match_operand:HF 2 "register_operand" "")))]
> + "CSKY_ISA_FEATURE(fpv3_hf)"
> + "")
>   
>   ;; -------------------------------------------------------------------------
>   ;; Float compare instructions
>   ;; -------------------------------------------------------------------------
>   
> -(define_expand "cbranchsf4"
> +(define_expand "cbranch<mode>4"
>     [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
> -			     [(match_operand:SF 1 "register_operand")
> -			      (match_operand:SF 2 "csky_compare_operand_float")])
> +			    [(match_operand:SFDF 1 "register_operand")
> +			     (match_operand:SFDF 2 "csky_compare_operand_float")])
>   			   (label_ref (match_operand 3 ""))
>   			   (pc)))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "
> -  {
> -    enum rtx_code code = GET_CODE (operands[0]);
> -    bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
> +"CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +"{
> +  enum rtx_code code = GET_CODE (operands[0]);
> +  bool invert;
>   
> -    if (invert)
> -      emit_jump_insn (gen_csky_jbf (operands[3]));
> -    else
> -      emit_jump_insn (gen_csky_jbt (operands[3]));
> +  invert = csky_emit_compare_float (code, operands[1], operands[2]);
>   
> -    DONE;
> -  }")
> -
> -(define_insn "*fpuv2_unordered"
> -  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
> -				  (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpuos\t%0, %1")
> -
> -(define_insn "*fpuv2_unordered_zero"
> -  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
> -				  (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpuos\t%0, %0")
> -
> -(define_insn "*fpuv2_ne"
> -  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpnes\t%0, %1")
> -
> -(define_insn "*fpuv2_gt"
> -  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmplts\t%1, %0")
> -
> -(define_insn "*fpuv2_ge"
> -  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_sf)"
> - "fcmphss\t%0, %1")
> -
> -(define_insn "*fpuv2_lt"
> -  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmplts\t%0, %1")
> -
> -(define_insn "*fpuv2_le"
> -  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
> -			   (match_operand:SF 1 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_sf)"
> - "fcmphss\t%1, %0")
> -
> -(define_insn "*fpuv2_gez"
> -  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand"	   "v")
> -			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpzhss\t%0")
> -
> -(define_insn "*fpuv2_nez"
> -  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand"	   "v")
> -			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fcmpznes\t%0")
> -
> -
> -(define_expand "cbranchdf4"
> -  [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
> -			     [(match_operand:DF 1 "register_operand")
> -			      (match_operand:DF 2 "csky_compare_operand_float")])
> -			   (label_ref (match_operand 3 ""))
> -			   (pc)))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "
> -  {
> -    enum rtx_code code = GET_CODE (operands[0]);
> -    bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
> +  if (invert)
> +    emit_jump_insn (gen_csky_jbf (operands[3]));
> +  else
> +    emit_jump_insn (gen_csky_jbt (operands[3]));
>   
> -    if (invert)
> -      emit_jump_insn (gen_csky_jbf (operands[3]));
> -    else
> -      emit_jump_insn (gen_csky_jbt (operands[3]));
> +  DONE;
>   
> -    DONE;
>   }")
>   
> -(define_insn "*fpuv2_dunordered"
> -  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
> -				  (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpuod\t%0, %1")
> -
> -(define_insn "*fpuv2_dunordered_zero"
> -  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
> -				  (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpuod\t%0, %0")
> -
> -(define_insn "*fpuv2_dne"
> -  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpned\t%0, %1")
> -
> -(define_insn "*fpuv2_dgt"
> -  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpltd\t%1, %0")
> -
> -(define_insn "*fpuv2_dge"
> -  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmphsd\t%0, %1")
> -
> -(define_insn "*fpuv2_dlt"
> -  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> - "CSKY_ISA_FEATURE (fpv2_df)"
> - "fcmpltd\t%0, %1")
> -
> -(define_insn "*fpuv2_dle"
> -  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
> -			   (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmphsd\t%1, %0")
> -
> -(define_insn "*fpuv2_dgez"
> -  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand"	   "v")
> -			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> - "CSKY_ISA_FEATURE (fpv2_df)"
> - "fcmpzhsd\t%0")
> -
> -(define_insn "*fpuv2_dnez"
> -  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand"	   "v")
> -			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fcmpzned\t%0")
> -
> +(define_expand "cbranchhf4"
> +  [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
> +			    [(match_operand:HF 1 "register_operand")
> +			     (match_operand:HF 2 "csky_compare_operand_float")])
> +			   (label_ref (match_operand 3 ""))
> +			   (pc)))]
> +"CSKY_ISA_FEATURE(fpv3_hf)"
> +"{
> +  enum rtx_code code = GET_CODE (operands[0]);
> +  bool invert;
>   
> -;; -------------------------------------------------------------------------
> -;; Float convert instructions
> -;; -------------------------------------------------------------------------
> +  invert = csky_emit_compare_float (code, operands[1], operands[2]);
>   
> -;; DF <- SF
> -(define_insn "extendsfdf2"
> -  [(set (match_operand:DF		   0 "register_operand" "=v")
> -	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fstod\t%0, %1")
> +  if (invert)
> +    emit_jump_insn (gen_csky_jbf (operands[3]));
> +  else
> +    emit_jump_insn (gen_csky_jbt (operands[3]));
>   
> -;; SF <- DF
> -(define_insn "truncdfsf2"
> -  [(set (match_operand:SF		     0 "register_operand" "=v")
> -	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fdtos\t%0, %1")
> -
> -;; SF <- SI
> -(define_insn "floatsisf2"
> -  [(set (match_operand:SF	    0 "register_operand" "=v")
> -	(float:SF (match_operand:SI 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fsitos\t%0, %1")
> -
> -;; DF <- SI
> -(define_insn "floatsidf2"
> -  [(set (match_operand:DF	    0 "register_operand" "=v")
> -	(float:DF (match_operand:SI 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fsitod\t%0, %1")
> -
> -;; SF <- unsigned SI
> -(define_insn "floatunssisf2"
> -  [(set (match_operand:SF		     0 "register_operand" "=v")
> -	(unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fuitos\t%0, %1")
> -
> -;; DF <- unsigned SI
> -(define_insn "floatunssidf2"
> -  [(set (match_operand:DF		     0 "register_operand" "=v")
> -	(unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fuitod\t%0, %1")
> -
> -;; SI <- SF
> -(define_insn "fix_truncsfsi2"
> -  [(set (match_operand:SI	  0 "register_operand" "=v")
> -	(fix:SI (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fstosi.rz\t%0, %1")
> -
> -;; SI <- DF
> -(define_insn "fix_truncdfsi2"
> -  [(set (match_operand:SI	  0 "register_operand" "=v")
> -	(fix:SI (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fdtosi.rz\t%0, %1")
> -
> -;; unsigned SI <- SF
> -(define_insn "fixuns_truncsfsi2"
> -  [(set (match_operand:SI		   0 "register_operand" "=v")
> -	(unsigned_fix:SI (match_operand:SF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "fstoui.rz\t%0, %1")
> -
> -;; unsigned SI <- DF
> -(define_insn "fixuns_truncdfsi2"
> -  [(set (match_operand:SI		   0 "register_operand" "=v")
> -	(unsigned_fix:SI (match_operand:DF 1 "register_operand" "v")))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "fdtoui.rz\t%0, %1")
> +  DONE;
>   
> +}")
>   
>   ;; -------------------------------------------------------------------------
> -;; Float mov instructions
> +;; Instructions for float cstore
>   ;; -------------------------------------------------------------------------
>   
> -;; Note:  movsf and movdf patterns are in csky.md.
> -
> -;; cstore SF
> -(define_expand "cstoresf4"
> +(define_expand "cstore<mode>4"
>     [(set (match_operand:SI 0 "register_operand" "")
> -	(match_operator	  1 "ordered_comparison_operator"
> -	  [(match_operand:SF 2 "register_operand" "")
> -	   (match_operand:SF 3 "csky_compare_operand_float" "")]))]
> -  "CSKY_ISA_FEATURE (fpv2_sf)"
> -  "
> -  {
> -    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
> -					   operands[2], operands[3]);
> -    if (invert)
> +	(match_operator   1 "csky_float_comparison_operator"
> +	  [(match_operand:SFDF 2 "register_operand" "")
> +	   (match_operand:SFDF 3 "csky_compare_operand_float" "")]))]
> +  "CSKY_ISA_FEATURE (fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "{
> +    bool invert;
> +
> +    invert = csky_emit_compare_float (GET_CODE (operands[1]),
> +				 operands[2], operands[3]);
> +    if(invert)
>         emit_insn (gen_mvcv (operands[0]));
>       else
>         emit_insn (gen_mvc (operands[0]));
> @@ -547,21 +332,91 @@
>     }"
>   )
>   
> -;; cstore DF
> -(define_expand "cstoredf4"
> +(define_expand "cstorehf4"
>     [(set (match_operand:SI 0 "register_operand" "")
> -	(match_operator 1 "ordered_comparison_operator"
> -	  [(match_operand:DF 2 "register_operand" "")
> -	   (match_operand:DF 3 "csky_compare_operand_float" "")]))]
> -  "CSKY_ISA_FEATURE (fpv2_df)"
> -  "
> -  {
> -    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
> -					   operands[2], operands[3]);
> -    if (invert)
> +	(match_operator   1 "csky_float_comparison_operator"
> +	  [(match_operand:HF 2 "register_operand" "")
> +	   (match_operand:HF 3 "csky_compare_operand_float" "")]))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "{
> +    bool invert;
> +
> +    invert = csky_emit_compare_float (GET_CODE (operands[1]),
> +				 operands[2], operands[3]);
> +    if(invert)
>         emit_insn (gen_mvcv (operands[0]));
>       else
>         emit_insn (gen_mvc (operands[0]));
>       DONE;
>     }"
>   )
> +
> +;; -------------------------------------------------------------------------
> +;; Float convert instructions
> +;; -------------------------------------------------------------------------
> +
> +;; SF <- HF
> +(define_expand "extendhfsf2"
> +  [(set (match_operand:SF		  0 "register_operand" "")
> +	(float_extend:SF (match_operand:HF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; HF <- SF
> +(define_expand "truncsfhf2"
> +  [(set (match_operand:HF		     0 "register_operand" "")
> +	(float_truncate:HF (match_operand:SF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; DF <- SF
> +(define_expand "extendsfdf2"
> +  [(set (match_operand:DF		  0 "register_operand" "")
> +	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
> +  "")
> +
> +;; SF <- DF
> +(define_expand "truncdfsf2"
> +  [(set (match_operand:SF		    0 "register_operand" "")
> +	(float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
> +  "")
> +
> +;; HF <- unsigned SI,SI
> +(define_expand "float<floatsuop>sihf2"
> +  [(set (match_operand:HF	   0 "register_operand" "")
> +	(FLOAT_SU:HF (match_operand:SI 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; DF,SF <- unsigned SI,SI
> +(define_expand "float<floatsuop>si<mode>2"
> +  [(set (match_operand:SFDF		    0 "register_operand" "")
> +	(FLOAT_SU:SFDF (match_operand:SI 1 "register_operand" "")))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
> +
> +;; DF,SF,HF <- unsigned HI,HI
> +;;(define_expand "float<floatsuop>hi<mode>2"
> +;;  [(set (match_operand:F3ANY	   0 "register_operand" "")
> +;;	(FLOAT_SU:F3ANY (match_operand:HI 1 "register_operand" "")))]
> +;;  "CSKY_ISA_FEATURE(fpv3_<mode>) && CSKY_ISA_FEATURE(fpv3_hi)"
> +;;  "")
> +
> +;; unsigned SI,SI <- HF
> +(define_expand "fix<fixsuop>_trunchfsi2"
> +  [(set (match_operand:SI	    0 "register_operand" "")
> +	(FIX_SU:SI (fix:HF (match_operand:HF 1 "register_operand" ""))))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "")
> +
> +;; unsigned SI,SI <- DF,SF
> +(define_expand "fix<fixsuop>_trunc<mode>si2"
> +  [(set (match_operand:SI	    0 "register_operand" "")
> +	(FIX_SU:SI (fix:SFDF (match_operand:SFDF 1 "register_operand" ""))))]
> +  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "")
> +
> +(include "csky_insn_fpuv3.md")
> +(include "csky_insn_fpuv2.md")
> diff --git a/gcc/config/csky/csky_insn_fpuv2.md b/gcc/config/csky/csky_insn_fpuv2.md
> new file mode 100644
> index 00000000000..0339deedb2e
> --- /dev/null
> +++ b/gcc/config/csky/csky_insn_fpuv2.md
> @@ -0,0 +1,470 @@
> +
> +;; -------------------------------------------------------------------------
> +;; Float Abs instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_abssf2"
> +  [(set (match_operand:SF	 0 "register_operand" "=v,a,r")
> +	(abs:SF (match_operand:SF 1 "register_operand" "v, 0,r")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "@
> +    fabss\t%0, %1
> +    bclri\t%0, %1, 31
> +    bclri\t%0, %1, 31"
> +  [(set_attr "length" "4,2,4")])
> +
> +(define_insn "*fpuv2_absdf2"
> +  [(set (match_operand:DF	 0 "register_operand" "=v")
> +	(abs:DF (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fabsd\t%0, %1")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Neg instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_negsf2"
> +  [(set (match_operand:SF	 0 "register_operand" "=v")
> +	(neg:SF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnegs\t%0, %1")
> +
> +(define_insn "*fpuv2_negdf2"
> +  [(set (match_operand:DF	 0 "register_operand" "=v")
> +	(neg:DF (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnegd\t%0, %1")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Sqrt instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_sqrtsf2"
> +  [(set (match_operand:SF	  0 "register_operand" "=v")
> +	(sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fsqrts\t%0, %1")
> +
> +(define_insn "*fpuv2_sqrtdf2"
> +  [(set (match_operand:DF	  0 "register_operand" "=v")
> +	(sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_divd)"
> + "fsqrtd\t%0, %1")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Add instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_addsf3"
> +  [(set (match_operand:SF	  0 "register_operand" "=v")
> +	(plus:SF (match_operand:SF 1 "register_operand" "v")
> +		 (match_operand:SF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fadds\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_adddf3"
> +  [(set (match_operand:DF	  0 "register_operand" "=v")
> +	(plus:DF (match_operand:DF 1 "register_operand" "v")
> +		 (match_operand:DF 2 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_df)"
> + "faddd\t%0, %1, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Sub instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_subsf3"
> +  [(set (match_operand:SF	   0 "register_operand" "=v")
> +	(minus:SF (match_operand:SF 1 "register_operand" "v")
> +		  (match_operand:SF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fsubs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_subdf3"
> +  [(set (match_operand:DF	   0 "register_operand" "=v")
> +	(minus:DF (match_operand:DF 1 "register_operand" "v")
> +		  (match_operand:DF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fsubd\t%0, %1, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Mul instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv2_mulsf3"
> +  [(set (match_operand:SF	  0 "register_operand" "=v")
> +	(mult:SF (match_operand:SF 1 "register_operand" "v")
> +		 (match_operand:SF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fmuls\t%0, %1, %2")
> +
> +(define_insn "*fpv2_muldf3"
> +  [(set (match_operand:DF	  0 "register_operand" "=v")
> +	(mult:DF (match_operand:DF 1 "register_operand" "v")
> +		 (match_operand:DF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fmuld\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_nmulsf3_1"
> +  [(set (match_operand:SF		  0 "register_operand" "=v")
> +	(mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
> +		 (match_operand:SF	 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
> +  "fnmuls\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_nmulsf3_2"
> +  [(set (match_operand:SF		  0 "register_operand" "=v")
> +	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> +			 (match_operand:SF 2 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnmuls\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_nmuldf3_1"
> +  [(set (match_operand:DF		  0 "register_operand" "=v")
> +	(mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
> +		 (match_operand:DF	 2 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
> + "fnmuld\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_nmuldf3_2"
> +  [(set (match_operand:DF		  0 "register_operand" "=v")
> +	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> +			 (match_operand:DF 2 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnmuld\t%0, %1, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float Div instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_divsf3"
> +  [(set (match_operand:SF	 0 "register_operand" "=v")
> +	(div:SF (match_operand:SF 1 "register_operand" "v")
> +		(match_operand:SF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fdivs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_1_divsf3"
> +  [(set (match_operand:SF	 0 "register_operand"	  "=v")
> +	(div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
> +		(match_operand:SF 2 "register_operand"	  "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "frecips\t%0, %2")
> +
> +(define_insn "*fpuv2_divdf3"
> +  [(set (match_operand:DF	 0 "register_operand" "=v")
> +	(div:DF (match_operand:DF 1 "register_operand" "v")
> +		(match_operand:DF 2 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_divd)"
> +  "fdivd\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_1_divdf3"
> +  [(set (match_operand:DF	 0 "register_operand"	  "=v")
> +	(div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
> +		(match_operand:DF 2 "register_operand"	  "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_divd)"
> +  "frecipd\t%0, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float add(sub) with mult instructions
> +;; -------------------------------------------------------------------------
> +
> +;; vrz <= vrz + vrx * vry
> +(define_insn "*fpuv2_fmacs"
> +  [(set (match_operand:SF		   0 "register_operand" "=v")
> +	(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> +			  (match_operand:SF 2 "register_operand" "v"))
> +		 (match_operand:SF	  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fmacs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fmacd"
> +  [(set (match_operand:DF		   0 "register_operand" "=v")
> +	(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> +			  (match_operand:DF 2 "register_operand" "v"))
> +		 (match_operand:DF	  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fmacd\t%0, %1, %2")
> +
> +;; vrz <= vrz - vrx * vry
> +(define_insn "*fpuv2_fnmacs"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(minus:SF (match_operand:SF	  1 "register_operand" "0")
> +		  (mult:SF (match_operand:SF 2 "register_operand" "v")
> +			   (match_operand:SF 3 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnmacs\t%0, %2, %3")
> +
> +(define_insn "*fpuv2_fnmacd"
> +  [(set (match_operand:DF		    0 "register_operand" "=v")
> +	(minus:DF (match_operand:DF	  1 "register_operand" "0")
> +		  (mult:DF (match_operand:DF 2 "register_operand" "v")
> +			   (match_operand:DF 3 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnmacd\t%0, %2, %3")
> +
> +;; vrz <= vrx * vry - vrz
> +(define_insn "*fpuv2_fmscs"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> +			   (match_operand:SF 2 "register_operand" "v"))
> +		  (match_operand:SF	  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fmscs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fmscd"
> +  [(set (match_operand:DF 0 "register_operand" "=v")
> +	(minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> +			   (match_operand:DF 2 "register_operand" "v"))
> +		  (match_operand:DF 3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fmscd\t%0, %1, %2")
> +
> +;; vrz = - (vrz + vrx * vry)
> +(define_insn "*fpuv2_fnmscs_1"
> +  [(set (match_operand:SF			    0 "register_operand" "=v")
> +	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
> +			   (match_operand:SF	 2 "register_operand" "v"))
> +		  (match_operand:SF		  3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnmscs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fnmscs_2"
> +  [(set (match_operand:SF			   0 "register_operand" "=v")
> +	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
> +				  (match_operand:SF 2 "register_operand" "v"))
> +			 (match_operand:SF	  3 "register_operand" "0"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fnmscs\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fnmscd_1"
> +  [(set (match_operand:DF 0 "register_operand" "=v")
> +	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
> +			   (match_operand:DF 2 "register_operand" "v"))
> +		  (match_operand:DF 3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnmscd\t%0, %1, %2")
> +
> +(define_insn "*fpuv2_fnmscd_2"
> +  [(set (match_operand:DF 0 "register_operand" "=v")
> +	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
> +				  (match_operand:DF 2 "register_operand" "v"))
> +			 (match_operand:DF 3 "register_operand" "0"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fnmscd\t%0, %1, %2")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float compare instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_unordered"
> +  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
> +				  (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpuos\t%0, %1")
> +
> +(define_insn "*fpuv2_unordered_zero"
> +  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
> +				  (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpuos\t%0, %0")
> +
> +(define_insn "*fpuv2_ne"
> +  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpnes\t%0, %1")
> +
> +(define_insn "*fpuv2_gt"
> +  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmplts\t%1, %0")
> +
> +(define_insn "*fpuv2_ge"
> +  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_sf)"
> + "fcmphss\t%0, %1")
> +
> +(define_insn "*fpuv2_lt"
> +  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmplts\t%0, %1")
> +
> +(define_insn "*fpuv2_le"
> +  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
> +			   (match_operand:SF 1 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_sf)"
> + "fcmphss\t%1, %0")
> +
> +(define_insn "*fpuv2_gez"
> +  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand"	  "v")
> +			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpzhss\t%0")
> +
> +(define_insn "*fpuv2_nez"
> +  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand"	  "v")
> +			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fcmpznes\t%0")
> +
> +(define_insn "*fpuv2_dunordered"
> +  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
> +				  (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpuod\t%0, %1")
> +
> +(define_insn "*fpuv2_dunordered_zero"
> +  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
> +				  (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpuod\t%0, %0")
> +
> +(define_insn "*fpuv2_dne"
> +  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpned\t%0, %1")
> +
> +(define_insn "*fpuv2_dgt"
> +  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpltd\t%1, %0")
> +
> +(define_insn "*fpuv2_dge"
> +  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmphsd\t%0, %1")
> +
> +(define_insn "*fpuv2_dlt"
> +  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> + "CSKY_ISA_FEATURE (fpv2_df)"
> + "fcmpltd\t%0, %1")
> +
> +(define_insn "*fpuv2_dle"
> +  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
> +			   (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmphsd\t%1, %0")
> +
> +(define_insn "*fpuv2_dgez"
> +  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand"	  "v")
> +			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> + "CSKY_ISA_FEATURE (fpv2_df)"
> + "fcmpzhsd\t%0")
> +
> +(define_insn "*fpuv2_dnez"
> +  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand"	  "v")
> +			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fcmpzned\t%0")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float convert instructions
> +;; -------------------------------------------------------------------------
> +
> +;; DF <- SF
> +(define_insn "*fpuv2_extendsfdf2"
> +  [(set (match_operand:DF		  0 "register_operand" "=v")
> +	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fstod\t%0, %1")
> +
> +;; SF <- DF
> +(define_insn "*fpuv2_truncdfsf2"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fdtos\t%0, %1")
> +
> +;; SF <- SI
> +(define_insn "*fpuv2_floatsisf2"
> +  [(set (match_operand:SF	   0 "register_operand" "=v")
> +	(float:SF (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fsitos\t%0, %1")
> +
> +;; DF <- SI
> +(define_insn "*fpuv2_floatsidf2"
> +  [(set (match_operand:DF	   0 "register_operand" "=v")
> +	(float:DF (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fsitod\t%0, %1")
> +
> +;; SF <- unsigned SI
> +(define_insn "*fpuv2_floatunssisf2"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fuitos\t%0, %1")
> +
> +;; DF <- unsigned SI
> +(define_insn "*fpuv2_floatunssidf2"
> +  [(set (match_operand:DF		    0 "register_operand" "=v")
> +	(unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fuitod\t%0, %1")
> +
> +;; SI <- SF
> +(define_insn "*fpuv2_fix_truncsfsi2"
> +  [(set (match_operand:SI	 0 "register_operand" "=v")
> +	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fstosi.rz\t%0, %1")
> +
> +;; SI <- DF
> +(define_insn "*fpuv2_fix_truncdfsi2"
> +  [(set (match_operand:SI	 0 "register_operand" "=v")
> +	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fdtosi.rz\t%0, %1")
> +
> +;; unsigned SI <- SF
> +(define_insn "*fpuv2_fixuns_truncsfsi2"
> +  [(set (match_operand:SI		  0 "register_operand" "=v")
> +	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "fstoui.rz\t%0, %1")
> +
> +;; unsigned SI <- DF
> +(define_insn "*fpuv2_fixuns_truncdfsi2"
> +  [(set (match_operand:SI		  0 "register_operand" "=v")
> +	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "fdtoui.rz\t%0, %1")
> +
> +
> +;; -------------------------------------------------------------------------
> +;; Float mov instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpuv2_movsf"
> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v")
> +	(match_operand:SF 1 "general_operand"      "r, F,r,v,r,m,v,Q,v,W"))]
> +  "CSKY_ISA_FEATURE (fpv2_sf)"
> +  "* return csky_output_move(insn, operands, SFmode);"
> +)
> +
> +(define_insn "*fpuv2_movdf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,v,?r,m,r,Q,v,v,v")
> +	(match_operand:DF 1 "general_operand"      "r, F,?r,v,r,m,v,Q,v,m"))]
> +  "CSKY_ISA_FEATURE (fpv2_df)"
> +  "* return csky_output_movedouble(operands, DFmode);"
> +  [(set (attr "length")
> +	(symbol_ref "get_output_csky_movedouble_length (operands)"))]
> +)
> diff --git a/gcc/config/csky/csky_insn_fpuv3.md b/gcc/config/csky/csky_insn_fpuv3.md
> new file mode 100644
> index 00000000000..5fc54049652
> --- /dev/null
> +++ b/gcc/config/csky/csky_insn_fpuv3.md
> @@ -0,0 +1,418 @@
> +
> +(define_c_enum "unspec" [
> +  UNSPEC_MAXNM_F3
> +  UNSPEC_MINNM_F3
> +])
> +
> +;; -------------------------------------------------------------------------
> +;; Float mov instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_movhf"
> +  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v, v")
> +	(match_operand:HF 1 "general_operand"      " r,F,r,v,r,m,v,Q,v,W,Dv"))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "*
> +  switch (which_alternative)
> +    {
> +    case 2:
> +      return \"fmtvr.16\\t%0, %1\";
> +    case 3:
> +      return \"fmfvr.16\\t%0, %1\";
> +    case 6:
> +    case 7:
> +    case 9:
> +      return fpuv3_output_move(operands);
> +    case 8:
> +      return \"fmov.16\\t%0, %1\";
> +    case 10:
> +      return \"fmovi.16\\t%0, %1\";
> +    case 1:
> +      {
> +	long bits;
> +	rtx ops[4];
> +
> +	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), HFmode);
> +	ops[0] = operands[0];
> +	ops[1] = GEN_INT (bits);
> +
> +	output_asm_insn (\"lrw\\t%0, %1\", ops);
> +	return \"\";
> +      }
> +    default:
> +      return csky_output_move(insn, operands, HFmode);
> +    }
> +  "
> +)
> +
> +(define_insn "*fpv3_movsf"
> +  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v, v")
> +	(match_operand:SF 1 "general_operand"      " r,F,r,v,r,m,v,Q,v,W,Dv"))]
> +  "CSKY_ISA_FEATURE(fpv3_sf)"
> +  "*
> +  switch (which_alternative)
> +    {
> +    case 2:
> +      return \"fmtvr.32.1\\t%0, %1\";
> +    case 3:
> +      return \"fmfvr.32.1\\t%0, %1\";
> +    case 6:
> +    case 7:
> +    case 9:
> +      return fpuv3_output_move(operands);
> +    case 8:
> +      return \"fmov.32\\t%0, %1\";
> +    case 10:
> +      return \"fmovi.32\\t%0, %1\";
> +    default:
> +      return csky_output_move(insn, operands, SFmode);
> +    }
> +  "
> +)
> +
> +(define_insn "*fpv3_movdf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,v,?r,m,r,Q,v,v,v,v")
> +	(match_operand:DF 1 "general_operand"      " r,F,?r,v,r,m,v,Q,v,m,Dv"))]
> +  "CSKY_ISA_FEATURE(fpv3_df)"
> +  "*
> +  switch (which_alternative)
> +    {
> +    case 2:
> +      if (TARGET_BIG_ENDIAN)
> +	return \"fmtvr.64\\t%0, %R1, %1\";
> +      return \"fmtvr.64\\t%0, %1, %R1\";
> +    case 3:
> +      if (TARGET_BIG_ENDIAN)
> +	return \"fmfvr.64\\t%R0, %0, %1\";
> +      return \"fmfvr.64\\t%0, %R0, %1\";
> +    case 6:
> +    case 7:
> +    case 9:
> +      return fpuv3_output_move(operands);
> +    case 8:
> +      return \"fmov.64\\t%0, %1\";
> +    case 10:
> +      return \"fmovi.64\\t%0, %1\";
> +    default:
> +      return csky_output_movedouble(operands, DFmode);
> +    }
> +  "
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float Mul instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_mul<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +		    (match_operand:F3ANY  2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fmul.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float Muladd and mulsub instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_mula<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "+v")
> +	(plus:F3ANY (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +				(match_operand:F3ANY  2 "register_operand" " v"))
> +		    (match_dup 0)))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fmula.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_muls<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "+v")
> +	(minus:F3ANY (match_dup 0)
> +		     (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +				 (match_operand:F3ANY  2 "register_operand" " v"))))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fmuls.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float fmula/fmuls/fnmula/fnmuls instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_fmuls_<mode>4"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(fma:F3ANY (neg:F3ANY (match_operand:F3ANY  1 "register_operand" "v"))
> +		   (match_operand:F3ANY   2 "register_operand" "v")
> +		   (match_operand:F3ANY   3 "register_operand"  "0")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "ffmuls.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_fmula_<mode>4"
> +  [(set (match_operand:F3ANY	    0 "register_operand" "=v")
> +	(fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
> +		   (match_operand:F3ANY 2 "register_operand" " v")
> +		   (match_operand:F3ANY 3 "register_operand" "0")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "ffmula.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_fnmula_<mode>4"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(neg: F3ANY (fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +			       (match_operand:F3ANY  2 "register_operand" " v")
> +			       (match_operand:F3ANY  3 "register_operand" "0"))))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "ffnmula.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_fnmuls_<mode>4"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +		   (match_operand:F3ANY  2 "register_operand" " v")
> +		   (neg:F3ANY (match_operand:F3ANY  3 "register_operand" "0"))))]
> +  "CSKY_ISA_FEATURE(fpv3_sf)"
> +  "ffnmuls.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float div/recipe/sqrt instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_div<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(div:F3ANY (match_operand:F3ANY   1 "register_operand" " v")
> +		   (match_operand:F3ANY   2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fdiv.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "*fpv3_recip<mode>3"
> +  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
> +	(div:F3ANY (match_operand:F3ANY  1 "csky_const_float1_operand" " i")
> +		   (match_operand:F3ANY  2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "frecip.<f3t>\t%0, %2"
> +)
> +
> +(define_insn "*fpv3_sqrt<mode>2"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(sqrt:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fsqrt.<f3t>\t%0, %1"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float fmax/fmin instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "fmax<mode>3"
> +  [(set (match_operand:F3ANY		 0 "register_operand" "=v")
> +	(unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
> +		       (match_operand:F3ANY  2 "register_operand" " v")]
> +		      UNSPEC_MAXNM_F3))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fmaxnm.<f3t>\t%0, %1, %2"
> +)
> +
> +(define_insn "fmin<mode>3"
> +  [(set (match_operand:F3ANY		 0 "register_operand" "=v")
> +	(unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
> +		       (match_operand:F3ANY  2 "register_operand" " v")]
> +		      UNSPEC_MINNM_F3))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fminnm.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float compare instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_<zero_inst>_<mode>3"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(FCMPZ:CC (match_operand:F3ANY 0 "register_operand" "v")
> +		  (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +   "fcmp<zero_inst>.<f3t>\t%0"
> +)
> +
> +(define_insn "*fpv3_<reg_inst>_<mode>3"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(FCMP:CC (match_operand:F3ANY 0 "register_operand" "v")
> +		 (match_operand:F3ANY 1 "register_operand" "v")))]
> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +   "fcmp<reg_inst>.<f3t>\t%0, %1"
> +)
> +
> +(define_insn "*fpv3_gt<mode>3"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(gt:CC (match_operand:F3ANY 0 "register_operand" "v")
> +	       (match_operand:F3ANY 1 "register_operand" "v")))]
> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +   "fcmplt.<f3t>\t%1, %0"
> +)
> +
> +(define_insn "*fpv3_le<mode>3"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(le:CC (match_operand:F3ANY 0 "register_operand" "v")
> +	       (match_operand:F3ANY 1 "register_operand" "v")))]
> +   "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +   "fcmphs.<f3t>\t%1, %0"
> +)
> +
> +(define_insn "*fpv3_unordered"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
> +		      (match_operand:F3ANY 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fcmpuo.<f3t>\t%0, %1")
> +
> +(define_insn "*fpv3_unordered_zero"
> +  [(set (reg:CC CSKY_CC_REGNUM)
> +	(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
> +		      (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fcmpuoz.<f3t>\t%0")
> +
> +;; -------------------------------------------------------------------------
> +;; Float ADD instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_add<mode>3"
> +  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
> +	(plus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +		    (match_operand:F3ANY  2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fadd.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float SUB instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_sub<mode>3"
> +  [(set (match_operand:F3ANY	       0 "register_operand" "=v")
> +	(minus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
> +		     (match_operand:F3ANY  2 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fsub.<f3t>\t%0, %1, %2"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float NEG instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_neg<mode>2"
> +  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
> +	(neg:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fneg.<f3t>\t%0, %1"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float ABS instructions
> +;; -------------------------------------------------------------------------
> +
> +(define_insn "*fpv3_abs<mode>2"
> +  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
> +	(abs:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fabs.<f3t>\t%0, %1"
> +)
> +
> +;; -------------------------------------------------------------------------
> +;; Float common convert instructions
> +;; -------------------------------------------------------------------------
> +
> +;; SF <- HF
> +(define_insn "*fpv3_extendhfsf2"
> +  [(set (match_operand:SF		  0 "register_operand" "=v")
> +	(float_extend:SF (match_operand:HF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "fhtos\t%0, %1")
> +
> +;; HF <- SF
> +(define_insn "*fpv3_truncsfhf2"
> +  [(set (match_operand:HF		     0 "register_operand" "=v")
> +	(float_truncate:HF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_hf)"
> +  "fstoh\t%0, %1")
> +
> +;; DF <- SF
> +(define_insn "*fpv3_extendsfdf2"
> +  [(set (match_operand:DF		  0 "register_operand" "=v")
> +	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_df)"
> +  "fstod\t%0, %1")
> +
> +;; SF <- DF
> +(define_insn "*fpv3_truncdfsf2"
> +  [(set (match_operand:SF		    0 "register_operand" "=v")
> +	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_df)"
> +  "fdtos\t%0, %1")
> +
> +;; DF,SF,HF <- unsigned SI,SI
> +(define_insn "*fpv3_float<floatsuop>si<mode>2"
> +  [(set (match_operand:F3ANY	   0 "register_operand" "=v")
> +	(FLOAT_SU:F3ANY (match_operand:SI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fitof.<floatsu>32.f<f3t>\t%0, %1")
> +
> +;; HF <- unsigned HI,HI
> +(define_insn "*fpv3_float<floatsuop>hihf2"
> +  [(set (match_operand:HF	   0 "register_operand" "=v")
> +	(FLOAT_SU:HF (match_operand:HI 1 "register_operand" "v")))]
> +  "CSKY_ISA_FEATURE(fpv3_hi)
> +   && CSKY_ISA_FEATURE(fpv3_hi)"
> +  "fitof.<floatsu>16.f16\t%0, %1")
> +
> +;; unsigned SI,SI <- DF,SF,HF
> +(define_insn "*fpv3_fix<fixsuop>_trunc<mode>si2"
> +  [(set (match_operand:SI	    0 "register_operand" "=v")
> +	(FIX_SU:SI (fix:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fftoi.f<f3t>.<fixsu>32.rz\t%0, %1")
> +
> +;; conversions need to be rounding to nearest.
> +
> +(define_insn "l<frm_pattern><fixsuop><mode>si2"
> +  [(set (match_operand:SI 0 "register_operand" "=v")
> +	(FIX_SU:SI (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")]
> +				   FRM)))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fftoi.f<f3t>.<fixsu>32<rm>\t%0, %1"
> +)
> +
> +(define_insn "<frm_pattern><mode>2"
> +  [(set (match_operand:F3ANY 0 "register_operand" "=v")
> +	(unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")] FRMF))]
> +  "CSKY_ISA_FEATURE(fpv3_<mode>)"
> +  "fftofi.f<f3t><rm>\t%0, %1"
> +)
> +
> +;; Write Floating-point Control Register.
> +(define_insn "csky_setfcrsi"
> +  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FCR)]
> +  "CSKY_ISA_FEATURE(fcr)"
> +  "mtcr\t%0, fcr"
> +)
> +
> +;; Read Floating-point Control Register.
> +(define_insn "csky_getfcrsi"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +	(unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FCR))]
> +  "CSKY_ISA_FEATURE(fcr)"
> +  "mfcr\t%0, fcr"
> +)
> +
> +;; Insert Floating-point Control Register.
> +(define_insn "csky_insfcrsi"
> +  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
> +		     (match_operand:SI 1 "const_int_operand" "i")
> +		     (match_operand:SI 2 "const_int_operand" "i")]VUNSPEC_INS_FCR)
> +   (clobber (reg: SI 13))]
> +  "CSKY_ISA_FEATURE(fcr)"
> +  {
> +    operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1);
> +    return "mfcr\tt1, fcr\n\tins\tt1, %0, %1, %2\n\tmtcr\tt1, fcr";
> +  }
> +)
> diff --git a/gcc/config/csky/csky_isa.def b/gcc/config/csky/csky_isa.def
> index e41e241c9c7..c971ccd3430 100644
> --- a/gcc/config/csky/csky_isa.def
> +++ b/gcc/config/csky/csky_isa.def
> @@ -32,6 +32,7 @@ CSKY_ISA (7E10,	 "Extended insns for arch ck810	 from ck807")
>   
>   /* Special insns */
>   CSKY_ISA (div,	  "divide insns")
> +CSKY_ISA (fcr,	  "Control the fcr register")
>   
>   /* Extended insns */
>   CSKY_ISA (dsp,	 "Extended insns for DSP")
> @@ -42,6 +43,11 @@ CSKY_ISA (fpv2_sf,    "Single precision operations supported")
>   CSKY_ISA (fpv2_df,    "Double precision operations supported")
>   CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
>   
> +CSKY_ISA (fpv3_hi,    "half word for fpu convert supported")
> +CSKY_ISA (fpv3_hf,    "half precision operations supported")
> +CSKY_ISA (fpv3_sf,    "Single precision operations supported")
> +CSKY_ISA (fpv3_df,    "Double precision operations supported")
> +
>   /* Specific insns mode */
>   #ifdef	CSKY_ISA_MACRO
>   #define CSKY_ISA_CK801	    CSKY_ISA_FEATURE_GET (E1)
> @@ -51,6 +57,7 @@ CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
>   #define CSKY_ISA_CK803R1    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E3r1)
>   #define CSKY_ISA_CK807	    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E7)
>   #define CSKY_ISA_CK810	    CSKY_ISA_CK807, CSKY_ISA_FEATURE_GET (7E10)
> +#define CSKY_ISA_CK860      CSKY_ISA_CK810, CSKY_ISA_FEATURE_GET(3E3r1)
>   
>   #define CSKY_ISA_DSP	    CSKY_ISA_FEATURE_GET (dsp)
>   #define CSKY_ISA_DSP2     CSKY_ISA_FEATURE_GET (dsp2)
> @@ -58,4 +65,12 @@ CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
>   #define CSKY_ISA_FPv2_SF    CSKY_ISA_FEATURE_GET (fpv2_sf)
>   #define CSKY_ISA_FPv2	    CSKY_ISA_FPv2_SF, CSKY_ISA_FEATURE_GET (fpv2_df)
>   #define CSKY_ISA_FPv2_DIVD  CSKY_ISA_FPv2, CSKY_ISA_FEATURE_GET (fpv2_divd)
> +
> +#define CSKY_ISA_FPv3_HF    CSKY_ISA_FEATURE_GET (fpv3_hf), \
> +                            CSKY_ISA_FEATURE_GET (fpv3_hi)
> +#define CSKY_ISA_FPv3_HSF   CSKY_ISA_FPv3_HF, \
> +                            CSKY_ISA_FEATURE_GET (fpv3_sf)
> +#define CSKY_ISA_FPv3_SDF   CSKY_ISA_FEATURE_GET (fpv3_sf), \
> +                            CSKY_ISA_FEATURE_GET (fpv3_df)
> +#define CSKY_ISA_FPv3       CSKY_ISA_FPv3_HF, CSKY_ISA_FPv3_SDF
>   #endif
> diff --git a/gcc/config/csky/csky_tables.opt b/gcc/config/csky/csky_tables.opt
> index f7202b23adb..3f7287ffef5 100644
> --- a/gcc/config/csky/csky_tables.opt
> +++ b/gcc/config/csky/csky_tables.opt
> @@ -194,6 +194,12 @@ Enum(csky_processor_type) String(ck810ft) Value( TARGET_CPU_ck810ff)
>   EnumValue
>   Enum(csky_processor_type) String(ck810ftv) Value( TARGET_CPU_ck810ftv)
>   
> +EnumValue
> +Enum(csky_processor_type) String(ck860) Value( TARGET_CPU_ck860)
> +
> +EnumValue
> +Enum(csky_processor_type) String(ck860f) Value( TARGET_CPU_ck860f)
> +
>   Enum
>   Name(csky_arch) Type(int)
>   Known CSKY architectures (for use with the -march= option):
> @@ -213,6 +219,9 @@ Enum(csky_arch) String(ck807) Value(3)
>   EnumValue
>   Enum(csky_arch) String(ck810) Value(4)
>   
> +EnumValue
> +Enum(csky_arch) String(ck860) Value(5)
> +
>   Enum
>   Name(csky_fpu) Type(enum csky_fpu_type)
>   Known CSKY FPUs (for use with the -mfpu= option):
> @@ -226,5 +235,17 @@ Enum(csky_fpu) String(fpv2) Value(TARGET_FPU_fpv2)
>   EnumValue
>   Enum(csky_fpu) String(fpv2_divd) Value(TARGET_FPU_fpv2_divd)
>   
> +EnumValue
> +Enum(csky_fpu) String(fpv3_hf) Value(TARGET_FPU_fpv3_hf)
> +
> +EnumValue
> +Enum(csky_fpu) String(fpv3_hsf) Value(TARGET_FPU_fpv3_hsf)
> +
> +EnumValue
> +Enum(csky_fpu) String(fpv3_sdf) Value(TARGET_FPU_fpv3_sdf)
> +
> +EnumValue
> +Enum(csky_fpu) String(fpv3) Value(TARGET_FPU_fpv3)
> +
>   EnumValue
>   Enum(csky_fpu) String(auto) Value(TARGET_FPU_auto)
> diff --git a/gcc/config/csky/predicates.md b/gcc/config/csky/predicates.md
> index 2aa012ab1f7..d919276e771 100644
> --- a/gcc/config/csky/predicates.md
> +++ b/gcc/config/csky/predicates.md
> @@ -297,5 +297,4 @@
>   })
>   
>   (define_special_predicate "csky_float_comparison_operator"
> -  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
> -	       unordered,ordered"))
> +  (match_code "eq,ne,le,lt,ge,gt,unordered,ordered"))
> diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
> index 2c67c818da5..5b2b26c22f9 100644
> --- a/gcc/doc/md.texi
> +++ b/gcc/doc/md.texi
> @@ -2258,6 +2258,14 @@ Vector registers.
>   
>   @item z
>   Stack pointer register (SP).
> +
> +@item Q
> +A memory address which uses a base register with a short offset
> +or with a index register with its scale.
> +
> +@item W
> +A memory address which uses a base register with a index register
> +with its scale.
>   @end table
>   
>   @ifset INTERNALS

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] C-SKY: Add fpuv3 instructions and CK860 arch
@ 2020-08-27  9:33 gengqi
  2020-09-07 11:27 ` Xianmiao Qu
  0 siblings, 1 reply; 5+ messages in thread
From: gengqi @ 2020-08-27  9:33 UTC (permalink / raw)
  To: gengqi, xianmiao_qu, gcc-patches; +Cc: gengq

From: gengq <qi_geng@c-sky.com>

gcc/ChangeLog:

	* config/csky/constraints.md (W): New constriant for mem operand with
	a base reg with a index register.
	(Q): Renamed and modified "csky_valid_fpuv2_mem_operand" to
	"csky_valid_mem_constraint_operand" to deal with both "Q" and "W"
	constraint.
	(Dv): New constraint for const double value that can be used at fmovi
	instruction.
	* config/csky/csky-modes.def (HFmode): New mode.
	* config/csky/csky-protos.h (csky_valid_mem_constraint_operand):
	Declare.
	(get_output_csky_movedouble_length): Declare.
	(fpuv3_output_move): Declare.
	(fpuv3_const_double): Declare.
	* config/csky/csky.c (csky_option_override): New arch CK860 with fpv3.
	(decompose_csky_address): Robustness adjust.
	(csky_print_operand): New "CONST_DOUBLE" operand.
	(csky_output_move): New support for fpv3 instructions.
	(get_output_csky_movedouble_length): New function.
	(fpuv3_output_move): New function.
	(fpuv3_const_double): New function.
	(csky_emit_compare): New cover for float comparsion.
	(csky_emit_compare_float): Refine.
	(csky_valid_mem_constraint_operand): Rename from
	"csky_valid_fpuv2_mem_operand" and new support for constraint "W".
	(ck860_rtx_costs): New function.
	(csky_rtx_costs): New subcall for CK860.
	* gcc/config/csky/csky.h (TARGET_TLS): Add CK860.
	* gcc/config/csky/csky.md (movsf): Delete, and achieve it at
	csky_insn_fpu.md.
	(ck801_movsf): Delete, and achieve it at csky_insn_fpu.md.
	(csky_movsf): Delete, and achieve it at csky_insn_fpu.md.
	(movdf): Delete, achieve it at csky_insn_fpu.md.
	(ck801_movdf): Delete, and achieve it at csky_insn_fpu.md.
	(csky_movdf): Delete, and achieve it at csky_insn_fpu.md.
	(csky_movsf_fpv2): Delete, and achieve it at csky_insn_fpuv2.md.
	(csky_movdf_fpv2): Delete, and achieve it at csky_insn_fpuv2.md.
	(movsicc): Refine. Use "comparison_operatior" instead of
	"ordered_comparison_operatior".
	(addsicc): Likewise.
	* config/csky/csky_cores.def (CK860): New arch and cpu.
	(fpv3_hf, fpv3_hsf, fpv3_sdf, fpv3): New fpus.
	* config/csky/csky_insn_fpu.md: Refactor. For fpuv2, separate all float
	patterns into emit-patterns and match-patterns, remain the
	emit-patterns here, and move the match-patterns to csky_insn_fpuv2.md.
	For fpuv3, add patterns and fuse part of them with the fpuv2's.
	* config/csky/csky_insn_fpuv2.md: New file for fpuv2 instructions.
	* config/csky/csky_insn_fpuv3.md: New flie and new patterns for fpuv3
	isntructions.
	* config/csky/csky_isa.def (fcr): New isa.
	(fpv3_hi, fpv3_hf, fpv3_sf, fpv3_df): New isa.
	(CK860): New definition.
	* gcc/config/csky/csky_tables.opt (ck860): New processors ck860,
	ck860f. And new arch ck860.
	(fpv3_hf, fpv3_hsf, fpv3_sdf, fpv3): New fpus.
	* config/csky/predicates.md (csky_float_comparsion_operator): Delete
	"geu", "gtu", "leu", "ltu", which will never appear at float
	comparison.
	* doc/md.texi: Add "Q" and "W" constraints for C-SKY.

---
 gcc/config/csky/constraints.md     |  13 +-
 gcc/config/csky/csky-modes.def     |   2 +
 gcc/config/csky/csky-protos.h      |   7 +-
 gcc/config/csky/csky.c             | 528 +++++++++++++++----
 gcc/config/csky/csky.h             |   2 +-
 gcc/config/csky/csky.md            | 120 +----
 gcc/config/csky/csky_cores.def     |  13 +
 gcc/config/csky/csky_insn_fpu.md   | 797 ++++++++++++-----------------
 gcc/config/csky/csky_insn_fpuv2.md | 470 +++++++++++++++++
 gcc/config/csky/csky_insn_fpuv3.md | 418 +++++++++++++++
 gcc/config/csky/csky_isa.def       |  15 +
 gcc/config/csky/csky_tables.opt    |  21 +
 gcc/config/csky/predicates.md      |   3 +-
 gcc/doc/md.texi                    |   8 +
 14 files changed, 1752 insertions(+), 665 deletions(-)
 create mode 100644 gcc/config/csky/csky_insn_fpuv2.md
 create mode 100644 gcc/config/csky/csky_insn_fpuv3.md

diff --git a/gcc/config/csky/constraints.md b/gcc/config/csky/constraints.md
index b9990b7dac9..874f698411b 100644
--- a/gcc/config/csky/constraints.md
+++ b/gcc/config/csky/constraints.md
@@ -34,7 +34,11 @@
 
 (define_memory_constraint "Q"
   "Memory operands with base register, index register and short displacement for FPUV2"
-  (match_test "csky_valid_fpuv2_mem_operand (op)"))
+  (match_test "csky_valid_mem_constraint_operand (op, \"Q\")"))
+
+(define_memory_constraint "W"
+  "memory operands with base register, index register"
+  (match_test "csky_valid_mem_constraint_operand (op, \"W\")"))
 
 (define_constraint "R"
   "Memory operands whose address is a label_ref"
@@ -172,3 +176,10 @@
   "Constant in range [-8, -1]"
   (and (match_code "const_int")
        (match_test "CSKY_CONST_OK_FOR_US (ival)")))
+
+(define_constraint "Dv"
+ "@VFPv3
+  A const_double which can be used with a VFP fmovi
+  instruction."
+ (and (match_code "const_double")
+      (match_test "fpuv3_const_double_rtx (op)")))
diff --git a/gcc/config/csky/csky-modes.def b/gcc/config/csky/csky-modes.def
index b76829fc2ac..ec5ee093674 100644
--- a/gcc/config/csky/csky-modes.def
+++ b/gcc/config/csky/csky-modes.def
@@ -1,3 +1,5 @@
+/* Float modes.  */
+FLOAT_MODE (HF, 2, ieee_half_format);        /* Half-precision floating point */
 
 /* Vector modes.  */
 VECTOR_MODES (INT, 4);  /* V4QI V2HI */
diff --git a/gcc/config/csky/csky-protos.h b/gcc/config/csky/csky-protos.h
index 2c023996d58..4ba59cc9b28 100644
--- a/gcc/config/csky/csky-protos.h
+++ b/gcc/config/csky/csky-protos.h
@@ -30,7 +30,7 @@ extern void csky_cpu_cpp_builtins (cpp_reader *);
 extern bool csky_inlinable_constant (HOST_WIDE_INT value);
 extern bool csky_shifted_imm8_constant (unsigned HOST_WIDE_INT,
 					unsigned int *, unsigned int *);
-extern bool csky_valid_fpuv2_mem_operand (rtx);
+extern bool csky_valid_mem_constraint_operand (rtx, const char*);
 
 extern bool csky_minipool_load_p (rtx_insn *);
 extern const char *csky_output_move (rtx insn, rtx *, machine_mode);
@@ -70,4 +70,9 @@ extern int csky_default_branch_cost (bool, bool);
 extern bool csky_default_logical_op_non_short_circuit (void);
 
 extern void csky_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+extern int get_output_csky_movedouble_length(rtx operands[]);
+
+/* The functions was used for fpuv3.  */
+extern const char *fpuv3_output_move (rtx *operands);
+extern int fpuv3_const_double_rtx (rtx);
 #endif /* GCC_CSKY_PROTOS_H */
diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
index 4de8aee4e77..ac082e06782 100644
--- a/gcc/config/csky/csky.c
+++ b/gcc/config/csky/csky.c
@@ -329,15 +329,15 @@ csky_cpu_cpp_builtins (cpp_reader *pfile)
       builtin_define ("__csky_hard_float__");
       builtin_define ("__CSKY_HARD_FLOAT__");
       if (TARGET_HARD_FLOAT_ABI)
-        {
-          builtin_define ("__csky_hard_float_abi__");
-          builtin_define ("__CSKY_HARD_FLOAT_ABI__");
-        }
+	{
+	  builtin_define ("__csky_hard_float_abi__");
+	  builtin_define ("__CSKY_HARD_FLOAT_ABI__");
+	}
       if (TARGET_SINGLE_FPU)
-        {
-          builtin_define ("__csky_hard_float_fpu_sf__");
-          builtin_define ("__CSKY_HARD_FLOAT_FPU_SF__");
-        }
+	{
+	  builtin_define ("__csky_hard_float_fpu_sf__");
+	  builtin_define ("__CSKY_HARD_FLOAT_FPU_SF__");
+	}
     }
   else
     {
@@ -698,7 +698,7 @@ csky_default_logical_op_non_short_circuit (void)
 #define	 TARGET_SCHED_ADJUST_COST csky_sched_adjust_cost
 
 /******************************************************************
- *           Construct vector Type and Builtin Function           *
+ *	   Construct vector Type and Builtin Function	   *
  ******************************************************************/
 
 #undef TARGET_VECTOR_MODE_SUPPORTED_P
@@ -853,6 +853,7 @@ Mfix *minipool_fix_tail;
 Mfix *minipool_barrier;
 
 /* Allow GC scanning of the minipool obstack.  */
+
 static void
 csky_add_gc_roots (void)
 {
@@ -862,6 +863,7 @@ csky_add_gc_roots (void)
 
 /* Implement TARGET_CONSTANT_ALIGNMENT.
    Make strings word-aligned so strcpy from constants will be faster.  */
+
 static HOST_WIDE_INT
 csky_constant_alignment (const_tree exp, HOST_WIDE_INT align)
 {
@@ -1125,6 +1127,7 @@ get_csky_barrier_cost (rtx_insn *insn)
    (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
    Create the barrier by inserting a jump and add a new fix entry for
    it.  */
+
 static Mfix *
 create_csky_fix_barrier (Mfix *fix, Mfix *fix_next,
 			 HOST_WIDE_INT max_address)
@@ -1471,6 +1474,7 @@ csky_compute_pushpop_length (rtx *operands)
 }
 
 /* Emit constant pools for -mconstpool.  */
+
 static void
 csky_emit_constant_pools (void)
 {
@@ -1812,6 +1816,7 @@ csky_initial_elimination_offset (int from, int to)
    CUM is a variable of type CUMULATIVE_ARGS which gives info about
     the preceding args and about the function being called.
    ARG is a description of the argument.  */
+
 static rtx
 csky_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
 {
@@ -1825,9 +1830,9 @@ csky_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
       reg = pcum->freg;
 
       if (reg < CSKY_NPARM_FREGS)
-        return gen_rtx_REG (mode, CSKY_FIRST_VFP_REGNUM + reg);
+	return gen_rtx_REG (mode, CSKY_FIRST_VFP_REGNUM + reg);
       else
-        return NULL_RTX;
+	return NULL_RTX;
     }
 
   if (reg < CSKY_NPARM_REGS)
@@ -1854,8 +1859,8 @@ csky_num_arg_regs (machine_mode mode, const_tree type, bool is_stdarg)
       && !is_stdarg)
     {
       if (CSKY_VREG_MODE_P(mode)
-          && !TARGET_SINGLE_FPU)
-        return ((CSKY_NUM_WORDS (size) + 1) / 2);
+	  && !TARGET_SINGLE_FPU)
+	return ((CSKY_NUM_WORDS (size) + 1) / 2);
     }
 
   return CSKY_NUM_WORDS (size);
@@ -1937,6 +1942,7 @@ csky_function_value (const_tree type, const_tree func,
 
 
 /* Implement TARGET_LIBCALL_VALUE.  */
+
 static rtx
 csky_libcall_value (machine_mode mode,
 		    const_rtx libcall ATTRIBUTE_UNUSED)
@@ -1957,7 +1963,7 @@ csky_function_value_regno_p (const unsigned int regno)
 {
   if (regno == CSKY_FIRST_RET_REGNUM
       || (TARGET_HARD_FLOAT_ABI
-          && regno == CSKY_FIRST_VFP_REGNUM))
+	  && regno == CSKY_FIRST_VFP_REGNUM))
     return true;
   return false;
 }
@@ -1965,6 +1971,7 @@ csky_function_value_regno_p (const unsigned int regno)
 
 /* Return an RTX indicating where the return address to the
    calling function can be found.  */
+
 rtx
 csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
 {
@@ -1980,6 +1987,7 @@ csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
    that must be put in registers. The value must be zero for arguments
    that are passed entirely in registers or
    that are entirely pushed on the stack.  */
+
 static int
 csky_arg_partial_bytes (cumulative_args_t pcum_v, const function_arg_info &arg)
 {
@@ -2214,6 +2222,7 @@ csky_conditional_register_usage (void)
 }
 
 /* Implement TARGET_HARD_REGNO_NREGS.  */
+
 static unsigned int
 csky_hard_regno_nregs (unsigned int regno, machine_mode mode)
 {
@@ -2277,6 +2286,7 @@ csky_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
 /* Implement TARGET_MODES_TIEABLE_P.  We can't tie DFmode with other modes
    when V_REGs might be in use because those registers mess with the stored
    bits.  */
+
 static bool
 csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 {
@@ -2288,6 +2298,7 @@ csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 /* Implement TARGET_CAN_CHANGE_MODE_CLASS.
    V_REG registers can't do subreg as all values are reformatted to
    internal precision.  */
+
 static bool
 csky_can_change_mode_class (machine_mode from,
 			    machine_mode to,
@@ -2422,6 +2433,7 @@ csky_spill_class (reg_class_t rclass, machine_mode mode ATTRIBUTE_UNUSED)
 
 /* Convert a static initializer array of feature bits to sbitmap
    representation.  */
+
 static void
 csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
 {
@@ -2433,6 +2445,7 @@ csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
 
 /* Configure a build target TARGET from the user-specified options OPTS and
    OPTS_SET.  */
+
 static void
 csky_configure_build_target (struct csky_build_target *target,
 			     struct cl_target_option *opts,
@@ -2524,7 +2537,9 @@ csky_option_override (void)
 
   csky_base_arch = csky_active_target.base_arch;
 
-  if (flag_pic && !(CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK807)))
+  if (flag_pic && !(CSKY_TARGET_ARCH (CK807)
+		   || CSKY_TARGET_ARCH (CK810)
+		   || CSKY_TARGET_ARCH (CK860)))
     {
       flag_pic = 0;
       warning (0, "%qs is not supported by arch %s",
@@ -2542,19 +2557,21 @@ csky_option_override (void)
 	  bool ok;
 	  int fpu_index;
 
-#ifdef CSKY_FPUTYPE_DEFAULT
-	  target_fpu_name = CSKY_FPUTYPE_DEFAULT;
-#else
-	  target_fpu_name = "fpv2";
-#endif
-
 	  if (csky_active_target.core_name != NULL
 	      && !strchr (csky_active_target.core_name, 'f'))
 	    target_fpu_name = "auto";
 	  else if (CSKY_TARGET_ARCH (CK803) || !TARGET_DOUBLE_FLOAT)
 	    target_fpu_name = "fpv2_sf";
+	  else if (CSKY_TARGET_ARCH (CK860))
+	    target_fpu_name = "fpv3";
 	  else if (TARGET_DOUBLE_FLOAT && TARGET_FDIVDU)
 	    target_fpu_name = "fpv2_divd";
+	  else
+#ifdef CSKY_FPUTYPE_DEFAULT
+	    target_fpu_name = CSKY_FPUTYPE_DEFAULT;
+#else
+	    target_fpu_name = "fpv2";
+#endif
 
 	  ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &fpu_index,
 				      CL_TARGET);
@@ -3247,7 +3264,10 @@ decompose_csky_address (rtx addr, struct csky_address *out)
 	      if (!base)
 		base = op;
 	      else if (!index)
-		index = op;
+		{
+		  index = op;
+		  scale = 1;
+		}
 	      else
 		return false;
 	      break;
@@ -3500,6 +3520,14 @@ csky_print_operand (FILE *stream, rtx x, int code)
 	case UNSPEC:
 	  csky_output_pic_addr_const (stream, x, code);
 	  break;
+	case CONST_DOUBLE:
+	  {
+	    char fpstr[20];
+	    real_to_decimal ( fpstr, CONST_DOUBLE_REAL_VALUE (x),
+			     sizeof (fpstr), 0, 1);
+	    fprintf (stream, "%s", fpstr);
+	  }
+	  break;
 	default:
 	  output_addr_const (stream, x);
 	  break;
@@ -4014,12 +4042,26 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	    }
 
 	    if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
-	      return "fmovs\t%0, %1";
+	      if (CSKY_ISA_FEATURE(fpv2_sf))
+		return "fmovs\t%0, %1";
+	      else if (CSKY_ISA_FEATURE(fpv3_sf))
+		return "fmov.32\t%0, %1";
+	      else
+		gcc_unreachable ();
 	    if (CSKY_VREG_P (dstreg))
-	      return "fmtvrl\t%0, %1";
+	      if (CSKY_ISA_FEATURE(fpv2_sf))
+		return "fmtvrl\t%0, %1";
+	      else if (CSKY_ISA_FEATURE(fpv3_sf))
+		return "fmtvr.32.1\t%0, %1";
+	      else
+		gcc_unreachable ();
 	    if (CSKY_VREG_P (srcreg))
-	      return "fmfvrl\t%0, %1";
-
+	      if (CSKY_ISA_FEATURE(fpv2_sf))
+		return "fmfvrl\t%0, %1";
+	      else if (CSKY_ISA_FEATURE(fpv3_sf))
+		return "fmfvr.32.1\t%0, %1";
+	      else
+		gcc_unreachable ();
 	    if (REGNO (src) == CSKY_CC_REGNUM)
 	      return "mvc\t%0";
 	    else
@@ -4040,12 +4082,19 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	      case E_SImode:
 	      case E_SFmode:
 		if (CSKY_VREG_P (REGNO (dst)))
-		  return "fldrs\t%0, %1";
+		  {
+		    if (CSKY_ISA_FEATURE(fpv2_sf))
+		      return "fldrs\t%0, %1";
+		    else if (CSKY_ISA_FEATURE(fpv3_sf))
+		      return "fldr.32\t%0, %1";
+		    else
+		      gcc_unreachable ();
+		    }
 		else
 		  return "ldr.w\t%0, %1";
-              case E_V4QImode:
-              case E_V2HImode:
-                return "ldr.w\t%0, %1";
+	      case E_V4QImode:
+	      case E_V2HImode:
+		return "ldr.w\t%0, %1";
 	      default:
 		gcc_unreachable ();
 	      }
@@ -4067,12 +4116,19 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	      case E_SFmode:
 	      case E_SImode:
 		if (CSKY_VREG_P (REGNO (dst)))
-		  return "flds\t%0, %1";
+		  {
+		     if (CSKY_ISA_FEATURE(fpv2_sf))
+		       return "flds\t%0, %1";
+		     else if (CSKY_ISA_FEATURE(fpv3_sf))
+		       return "fld.32\t%0, %1";
+		     else
+		       gcc_unreachable ();
+		   }
 		else
 		  return "ld.w\t%0, %1";
-              case E_V4QImode:
-              case E_V2HImode:
-                return "ld.w\t%0, %1";
+	      case E_V4QImode:
+	      case E_V2HImode:
+		return "ld.w\t%0, %1";
 	      default:
 		gcc_unreachable ();
 	      }
@@ -4128,12 +4184,19 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	  case E_SFmode:
 	  case E_SImode:
 	    if (CSKY_VREG_P (REGNO (src)))
-	      return "fstrs\t%1, %0";
+	      {
+		if (CSKY_ISA_FEATURE(fpv2_sf))
+		  return "fstrs\t%1, %0";
+		else if (CSKY_ISA_FEATURE(fpv3_sf))
+		  return "fstr.32\t%1, %0";
+		else
+		  gcc_unreachable ();
+	      }
 	    else
 	      return "str.w\t%1, %0";
-          case E_V4QImode:
-          case E_V2HImode:
-            return "str.w\t%1, %0";
+	  case E_V4QImode:
+	  case E_V2HImode:
+	    return "str.w\t%1, %0";
 	  default:
 	    gcc_unreachable ();
 	  }
@@ -4147,12 +4210,19 @@ csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
 	  case E_SImode:
 	  case E_SFmode:
 	    if (CSKY_VREG_P (REGNO (src)))
-	      return "fsts\t%1, %0";
+	      {
+		if (CSKY_ISA_FEATURE(fpv2_sf))
+		  return "fsts\t%1, %0";
+		else if (CSKY_ISA_FEATURE(fpv3_sf))
+		  return "fst.32\t%1, %0";
+		else
+		  gcc_unreachable ();
+	      }
 	    else
 	      return "st.w\t%1, %0";
-          case E_V4QImode:
-          case E_V2HImode:
-            return "st.w\t%1, %0";
+	  case E_V4QImode:
+	  case E_V2HImode:
+	    return "st.w\t%1, %0";
 	  default:
 	    gcc_unreachable ();
 	  }
@@ -4289,7 +4359,14 @@ csky_output_movedouble (rtx operands[],
 		return "mthi\t%R1\n\tmtlo\t%1";
 	    }
 	  else if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
-	    return "fmovd\t%0, %1";
+	    {
+	      if (CSKY_ISA_FEATURE(fpv2_df))
+		return "fmovd\t%0, %1";
+	      else if (CSKY_ISA_FEATURE(fpv3_df))
+		return "fmov.64\t%0, %1";
+	      else
+		gcc_unreachable ();
+	    }
 	  else if (CSKY_VREG_P (srcreg))
 	    {
 	      /* Since the vector registers in fpuv2_soft processors
@@ -4298,18 +4375,46 @@ csky_output_movedouble (rtx operands[],
 	      if (TARGET_SOFT_FPU)
 		  return "fmfvrl\t%0, %1";
 	      else if (TARGET_BIG_ENDIAN)
-		return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fmfvr.64\t%R0, %0, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	      else
-		return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fmfvr.64\t%0, %R0, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	    }
 	  else if (CSKY_VREG_P (dstreg))
 	    {
 	      if (TARGET_SOFT_FPU)
 		return "fmtvrl\t%0, %1";
 	      else if (TARGET_BIG_ENDIAN)
-		return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fmtvr.64\t%0, %R1, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	      else
-		return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fmtvr.64\t%0, %1, %R1";
+		  else
+		    gcc_unreachable ();
+		}
 	    }
 
 	  /* Ensure the second source not overwritten.  */
@@ -4351,9 +4456,23 @@ csky_output_movedouble (rtx operands[],
 	  if (CSKY_VREG_P (dstreg))
 	    {
 	      if (op0.index)
-		return "fldrd\t%0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fldrd\t%0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fldr.64\t%0, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	      else
-		return "fldd\t%0, %1";
+		{
+		  if (CSKY_ISA_FEATURE(fpv2_df))
+		    return "fldd\t%0, %1";
+		  else if (CSKY_ISA_FEATURE(fpv3_df))
+		    return "fld.64\t%0, %1";
+		  else
+		    gcc_unreachable ();
+		}
 	    }
 	  /* FIXME length attribute is wrong here.  */
 	  if (dstreg == basereg)
@@ -4417,9 +4536,23 @@ csky_output_movedouble (rtx operands[],
       if (CSKY_VREG_P (srcreg))
 	{
 	  if (op0.index)
-	    return "fstrd\t%1, %0";
+	    {
+	      if (CSKY_ISA_FEATURE(fpv2_df))
+		return "fstrd\t%1, %0";
+	      else if (CSKY_ISA_FEATURE(fpv3_df))
+		return "fstr.64\t%1, %0";
+	      else
+		gcc_unreachable ();
+	    }
 	  else
-	    return "fstd\t%1, %0";
+	    {
+	      if (CSKY_ISA_FEATURE(fpv2_df))
+		return "fstd\t%1, %0";
+	      else if (CSKY_ISA_FEATURE(fpv3_df))
+		return "fst.64\t%1, %0";
+	      else
+		gcc_unreachable ();
+	    }
 	}
       /* FIXME length attribute is wrong here.  */
       if (srcreg == basereg)
@@ -4546,9 +4679,185 @@ csky_output_ck801_movedouble (rtx operands[],
     gcc_unreachable ();
 }
 
+/* Calculate the cost of insn for moving double-word data.  */
+
+int
+get_output_csky_movedouble_length(rtx operands[])
+{
+  rtx dst = operands[0];
+  rtx src = operands[1];
+
+  if (REG_P (dst))
+    {
+      if (REG_P (src))
+	{
+	  int dstreg = REGNO (dst);
+	  int srcreg = REGNO (src);
+
+	  if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
+	    return 4;
+	  else
+	    return 8;
+	}
+      else if (GET_CODE (src) == MEM)
+	{
+	  rtx memexp = XEXP (src, 0);
+	  int dstreg = REGNO (dst);
+	  int basereg = -1;
+	  struct csky_address op0;
+	  decompose_csky_address (XEXP (src, 0), &op0);
+
+	  if (GET_CODE (memexp) == LABEL_REF)
+	    return 8;
+	  if (CSKY_VREG_P (dstreg))
+	    return 4;
+	  return 8;
+	}
+      else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
+	{
+	  split_double (src, operands + 2, operands + 3);
+	  if (CSKY_CONST_OK_FOR_N (INTVAL (operands[2]) + 1)
+	      && CSKY_CONST_OK_FOR_N (INTVAL (operands[3]) + 1)
+	      && REGNO (operands[0]) < 6)
+	    return 4;
+	  else
+	    return 8;
+	}
+    }
+  else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
+    {
+      rtx memexp = XEXP (dst, 0);
+      int srcreg = REGNO (src);
+      int offset = -1;
+      if (CSKY_VREG_P (srcreg))
+	return 4;
+
+      if (GET_CODE (memexp) == REG)
+	offset = 0;
+      else if (GET_CODE (memexp) == PLUS)
+	{
+	  if (GET_CODE (XEXP (memexp, 0)) == REG)
+	    offset = INTVAL (XEXP (memexp, 1));
+	  else if (GET_CODE (XEXP (memexp, 1)) == REG)
+	    offset = INTVAL (XEXP (memexp, 0));
+	  else
+	    gcc_unreachable ();
+	}
+      else
+	gcc_unreachable ();
+
+      if (srcreg <= 6 && offset <= 1020)
+	return 4;
+      else if ((srcreg == 7 && offset <= 1024) || (srcreg <= 7 && offset == 1024))
+	return 6;
+      else
+	return 8;
+    }
+  else
+    gcc_unreachable ();
+}
+
+/* Output string for float point load/store instructions
+   for fpuv3.  */
+
+const char *
+fpuv3_output_move (rtx *operands)
+{
+  rtx reg, mem, addr, ops[2];
+  int load = REG_P (operands[0]);
+
+  const char *templ = "f%s%s.%s\t%%0, %%1";
+  char buff[50];
+  machine_mode mode;
+
+  reg = operands[!load];
+  mem = operands[load];
+
+  gcc_assert (REG_P (reg));
+  gcc_assert (CSKY_VREG_P (REGNO (reg)));
+  gcc_assert (MEM_P (mem));
+
+  mode = GET_MODE (reg);
+  const char *type = mode == DFmode ? "64" :
+		     mode == SFmode ? "32" :
+		     mode == HFmode ? "16" :
+		     NULL;
+  gcc_assert(type != NULL);
+
+  addr = XEXP (mem, 0);
+  struct csky_address caddr;
+  decompose_csky_address (addr, &caddr);
+
+  ops[0] = reg;
+  ops[1] = mem;
+  sprintf (buff, templ,
+	   load ? "ld" : "st",
+	   caddr.index ? "r" : "",
+	   type);
+  output_asm_insn (buff, ops);
+
+  return "";
+}
+
+/* Check if a const_double can be used with a VFP fmovi
+   instruction.  */
+
+int
+fpuv3_const_double_rtx (rtx x)
+{
+  REAL_VALUE_TYPE r, m;
+  r = *CONST_DOUBLE_REAL_VALUE (x);
+
+  /* Fpuv3 can't represent these things, so detect them first.  */
+  if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r) || REAL_VALUE_MINUS_ZERO (r)
+      || r.cl == rvc_zero)
+    return 0;
+
+  /* Extract sign, exponent and mantissa.  */
+  int sign, exponent;
+  sign = REAL_VALUE_NEGATIVE (r) ? 1 : 0;
+  r = real_value_abs (&r);
+  exponent = REAL_EXP (&r);
+
+  bool fail;
+  unsigned HOST_WIDE_INT mantissa, mant_hi;
+  unsigned HOST_WIDE_INT mask;
+  int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1;
+  real_ldexp (&m, &r, point_pos - exponent);
+  wide_int w = real_to_integer (&m, &fail, HOST_BITS_PER_WIDE_INT * 2);
+  mantissa = w.elt (0);
+  mant_hi = w.elt (1);
+
+  exponent -= 1;
+
+  if (!IN_RANGE (exponent, -4, 11))
+    return 0;
+
+  /* If there are bits set in the low part of the mantissa, we can't
+     represent this value.  */
+  if (mantissa != 0)
+    return 0;
+
+  /* Now make it so that mantissa contains the most-significant bits, and move
+     the point_pos to indicate that the least-significant bits have been
+     discarded.  */
+  point_pos -= HOST_BITS_PER_WIDE_INT;
+  mantissa = mant_hi;
+
+  /* We can permit 8 significant bits of mantissa only, plus a high bit
+     which is always 1.  */
+  mask = ((unsigned HOST_WIDE_INT)1 << (point_pos - 9)) - 1;
+  if ((mantissa & mask) != 0)
+    return 0;
+
+  return 1;
+}
+
+
 /* Split operands for an AND expression when OPERANDS[2] is a constant.
    Note operands[0] is marked earlyclobber in this case and can be
    overwritten.  Return true if "DONE", false otherwise.  */
+
 bool
 csky_split_and (rtx *operands)
 {
@@ -4678,6 +4987,7 @@ csky_split_and (rtx *operands)
 /* Split operands for an IOR expression when OPERANDS[2] is a constant.
    Note operands[0] is marked earlyclobber in this case and can be
    overwritten.  Return true if "DONE", false otherwise.  */
+
 bool
 csky_split_ior (rtx *operands)
 {
@@ -4745,6 +5055,7 @@ csky_split_ior (rtx *operands)
 /* Split operands for an XOR expression when OPERANDS[2] is a constant.
    Note operands[0] is marked earlyclobber in this case and can be
    overwritten.  Return true if "DONE", false otherwise.  */
+
 bool
 csky_split_xor (rtx *operands)
 {
@@ -4793,6 +5104,7 @@ csky_split_xor (rtx *operands)
 
 
 /* Return true if X is an address form involving a symbol or label ref.  */
+
 bool
 csky_symbolic_address_p (rtx x)
 {
@@ -4821,6 +5133,9 @@ csky_emit_compare (enum rtx_code code, rtx op0, rtx op1)
   bool invert;
   rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
 
+  if (GET_MODE_CLASS(GET_MODE (op0)) == MODE_FLOAT)
+    return csky_emit_compare_float(code, op0, op1);
+
   if (GET_CODE (op1) == CONST_INT)
     {
       HOST_WIDE_INT val = INTVAL (op1);
@@ -5735,6 +6050,7 @@ tls_unspec_mentioned_p (rtx x)
 
 
 /* Implement LEGITIMATE_PIC_OPERAND_P.  */
+
 bool
 csky_legitimate_pic_operand_p (rtx x)
 {
@@ -5965,33 +6281,20 @@ csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
     op1 = force_reg (mode, op1);
 
   invert = false;
+
   switch (code)
     {
     case EQ:
       code = NE;
       invert = true;
       break;
-
-    case NE:
-      break;
-    case LE:
-      if (op1 == CONST0_RTX (mode))
-	op1 = force_reg (mode, op1);
-      break;
     case GT:
-      if (op1 == CONST0_RTX (mode))
-	op1 = force_reg (mode, op1);
-      break;
-    case GE:
-      break;
     case LT:
-      if (op1 == CONST0_RTX (mode))
-	{
-	  code = GE;
-	  invert = true;
-	}
-      break;
-    case UNORDERED:
+    case LE:
+      if (op1 == CONST0_RTX (mode) && (CSKY_ISA_FEATURE_GET(fpv2_sf)
+				       || CSKY_ISA_FEATURE_GET(fpv2_df)
+				       || CSKY_ISA_FEATURE_GET(fpv2_divd)))
+	op1 = force_reg (mode, op1);
       break;
     case ORDERED:
       code = UNORDERED;
@@ -6007,10 +6310,11 @@ csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
   return invert;
 }
 
-/* Support for the Q memory constraint.  Returns true if OP is a MEM RTX
-   with an address consisting of base + index or base + displacement.  */
+/* Support for the Q or W memory constraint.  Returns true if OP is a MEM
+   RTX with an address consisting of base + index or base + displacement.  */
+
 bool
-csky_valid_fpuv2_mem_operand (rtx op)
+csky_valid_mem_constraint_operand (rtx op, const char *constraint)
 {
   struct csky_address addr;
 
@@ -6025,7 +6329,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
     return false;
 
   /* Verify index operand. */
-  if (addr.index)
+  if (addr.index && (constraint[0] == 'Q' || constraint[0] == 'W'))
     {
       if (!is_csky_address_register_rtx_p (addr.index, 0))
 	return false;
@@ -6037,7 +6341,7 @@ csky_valid_fpuv2_mem_operand (rtx op)
       return false;
     }
   /* Verify disp operand.  */
-  else if (addr.disp)
+  else if (addr.disp && constraint[0] == 'Q')
     {
       rtx disp = addr.disp;
 
@@ -6469,7 +6773,7 @@ ck803_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
     }
 }
 
-/* TARGET_RTX_COSTS helper for ck807+ arches.  */
+/* TARGET_RTX_COSTS helper for ck807/ck810 arches.  */
 
 static bool
 ck807_ck810_rtx_costs (rtx x, int code,
@@ -6500,6 +6804,52 @@ ck807_ck810_rtx_costs (rtx x, int code,
     }
 }
 
+/* TARGET_RTX_COSTS helper for ck860 arches.  */
+
+static bool
+ck860_rtx_costs (rtx x, int code, machine_mode mode,
+		 int outer_code ATTRIBUTE_UNUSED,
+		 int *total, bool speed ATTRIBUTE_UNUSED)
+{
+  switch (code)
+    {
+    case PLUS:
+      /* The costs of mula is 1 more than mult.  */
+      if (GET_CODE (XEXP (x, 0)) == MULT && REG_P (XEXP (x, 1)) && speed)
+	{
+	  rtx mul_op0 = XEXP (XEXP (x, 0), 0);
+	  rtx mul_op1 = XEXP (XEXP (x, 0), 1);
+	  if (REG_P (mul_op0) && REG_P (mul_op1))
+	    {
+	      *total = COSTS_N_INSNS (1);
+	      *total += rtx_cost (XEXP (x, 0), mode,
+				  (enum rtx_code) code, 0, speed);
+	      return true;
+	    }
+	}
+      return false;
+    case MULT:
+      if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
+	{
+	  HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
+	  if (val % 2 == 0 && val < 0xffffffff && val > 0)
+	    {
+	      *total = COSTS_N_INSNS (1);
+	      return true;
+	    }
+	}
+      return false;
+
+    case CONST:
+    case LABEL_REF:
+    case SYMBOL_REF:
+      *total = COSTS_N_INSNS (3);
+      return true;
+    default:
+      return false;
+    }
+}
+
 
 /* Implement TARGET_RTX_COSTS, to compute a (partial) cost for rtx X.
    Return true if the complete cost has been computed, and false if
@@ -6518,6 +6868,8 @@ csky_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
     return ck803_rtx_costs (x, code, outer_code, total, speed);
   else if (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
     return ck807_ck810_rtx_costs (x, code, outer_code, total, speed);
+  else if (CSKY_TARGET_ARCH (CK860))
+    return ck860_rtx_costs (x, code, mode, outer_code, total, speed);
   else
     gcc_unreachable ();
 }
@@ -6660,6 +7012,7 @@ csky_warn_func_return (tree decl)
 /* Implement TARGET_RETURN_IN_MEMORY to decide whether TYPE should be
    returned in memory (true) or in a register (false).
    FNTYPE is the type of the function making the call.  */
+
 static bool
 csky_return_in_memory (const_tree type,
 		       const_tree fntype ATTRIBUTE_UNUSED)
@@ -6673,6 +7026,7 @@ csky_return_in_memory (const_tree type,
    Dwarf models VFP registers as  64-bit or 128-bit registers default.
    GCC models tham as 32-bit registers, so we need to describe this to
    the DWARF generation code.  Other registers can use the default.  */
+
 static rtx
 csky_dwarf_register_span (rtx rtl)
 {
@@ -6866,8 +7220,8 @@ csky_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
 
 void
 csky_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
-                           rtx libname ATTRIBUTE_UNUSED,
-                           tree fndecl ATTRIBUTE_UNUSED)
+			   rtx libname ATTRIBUTE_UNUSED,
+			   tree fndecl ATTRIBUTE_UNUSED)
 {
   memset(pcum, 0, sizeof(*pcum));
   if (stdarg_p (fntype))
@@ -6882,7 +7236,7 @@ csky_vector_mode_supported_p (machine_mode mode)
 {
   if (CSKY_ISA_FEATURE (dsp2)
       && (mode == V4QImode || mode == V2HImode
-          || mode == V2SImode || mode == V4HImode))
+	  || mode == V2SImode || mode == V4HImode))
     return true;
 
   return false;
@@ -6897,14 +7251,14 @@ csky_preferred_simd_mode (scalar_mode mode)
   if (CSKY_ISA_FEATURE (dsp2))
     {
       switch (mode)
-        {
-        case E_QImode:
-          return V4QImode;
-        case E_HImode:
-          return V2HImode;
-        default:
-          break;
-        }
+	{
+	case E_QImode:
+	  return V4QImode;
+	case E_HImode:
+	  return V2HImode;
+	default:
+	  break;
+	}
     }
   return word_mode;
 }
diff --git a/gcc/config/csky/csky.h b/gcc/config/csky/csky.h
index 5abdeda3e67..a4c76ec7a38 100644
--- a/gcc/config/csky/csky.h
+++ b/gcc/config/csky/csky.h
@@ -124,7 +124,7 @@
   (optimize_size && TARGET_CONSTANT_POOL \
    && (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802)))
 #define TARGET_TLS \
-  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
+  (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK860))
 
 /* Run-time Target Specification.  */
 #define TARGET_SOFT_FLOAT       (csky_float_abi == CSKY_FLOAT_ABI_SOFT)
diff --git a/gcc/config/csky/csky.md b/gcc/config/csky/csky.md
index a4f3d284812..e99ab799e9c 100644
--- a/gcc/config/csky/csky.md
+++ b/gcc/config/csky/csky.md
@@ -425,85 +425,6 @@
    (set_attr "type" "alu,alu,alu,load,load,store")]
 )
 
-;; Float mov instructions.
-
-(define_expand "movsf"
-  [(set (match_operand:SF 0 "general_operand" "")
-	(match_operand:SF 1 "general_operand" ""))]
-  ""
-  "
-  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
-    operands[1] = force_reg (SFmode, operands[1]);
-  "
-)
-
-;; FIXME: maybe the vreg load/stores should have their own type attr.
-(define_insn "*csky_movsf_fpv2"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v")
-	(match_operand:SF 1 "general_operand"	   " b,r,r,v,m,mF,r,v,Q,v,m"))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "* return csky_output_move (insn, operands, SFmode);"
-  [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4")
-   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
-)
-
-(define_insn "*ck801_movsf"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
-	(match_operand:SF 1 "general_operand"	   " r,m,mF,r"))]
-  "CSKY_ISA_FEATURE (E1)"
-  "* return csky_output_ck801_move (insn, operands, SFmode);"
-  [(set_attr "length" "2,4,4,4")
-   (set_attr "type" "alu,load,load,store")]
-)
-
-(define_insn "*csky_movsf"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
-	(match_operand:SF 1 "general_operand"	   " b,r,m,mF,r"))]
-  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_sf)"
-  "* return csky_output_move (insn, operands, SFmode);"
- [(set_attr "length" "2,4,4,4,4")
-  (set_attr "type" "alu,alu,load,load,store")]
-)
-
-
-(define_expand "movdf"
-  [(set (match_operand:DF 0 "general_operand" "")
-	(match_operand:DF 1 "general_operand" ""))]
-  ""
-  "
-  if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ())
-      operands[1] = force_reg (DFmode, operands[1]);
-  "
-)
-
-;; FIXME: maybe the vreg load/stores should have their own type attr.
-(define_insn "*csky_movdf_fpv2"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v")
-	(match_operand:DF 1 "general_operand"	    "b,r,r,v,m,mF,r,v,Q,v,m"))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "* return csky_output_movedouble (operands, DFmode);"
-  [(set_attr "length" "4,8,8,8,8,8,8,8,8,8,8")
-   (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")]
-)
-
-(define_insn "*ck801_movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
-	(match_operand:DF 1 "general_operand"	   " r,m,mF,r"))]
-  "CSKY_ISA_FEATURE (E1)"
-  "* return csky_output_ck801_movedouble (operands, DFmode);"
-  [(set_attr "length" "4,8,8,8")
-   (set_attr "type" "alu,load,load,store")]
-)
-
-(define_insn "*csky_movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
-	(match_operand:DF 1 "general_operand"	   " b,r,m,mF,r"))]
-  "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_df)"
-  "* return csky_output_movedouble (operands, DFmode);"
- [(set_attr "length" "4,8,8,8,8")
-  (set_attr "type" "alu,alu,load,load,store")]
-)
-
 ;; The only CCmode move supported is a nop.  Without this pattern,
 ;; CSE is unable to eliminate redundant comparisons in conditional
 ;; execution expressions.
@@ -524,7 +445,7 @@
 
 (define_expand "movsicc"
   [(set (match_operand 0 "register_operand" "")
-	(if_then_else:SI (match_operand	   1 "ordered_comparison_operator" "")
+	(if_then_else:SI (match_operand	   1 "comparison_operator" "")
 			 (match_operand:SI 2 "register_operand" "")
 			 (match_operand:SI 3 "register_operand" "")))]
   "CSKY_ISA_FEATURE (E2)"
@@ -916,7 +837,7 @@
   if (CSKY_ISA_FEATURE (E1) && (GET_CODE (operands[2]) != REG))
       operands[2] = force_reg (DImode, operands[2]);
   else if (CSKY_ISA_FEATURE (dsp2) && (REG_P (operands[2])
-                                       || SUBREG_P (operands[2])))
+				       || SUBREG_P (operands[2])))
     {
       emit_insn (gen_dsp2_adddi3 (operands[0], operands[1], operands[2]));
       DONE;
@@ -1335,7 +1256,7 @@
 
 (define_expand "addsicc"
   [(match_operand:SI 0 "register_operand" "")
-   (match_operand    1 "ordered_comparison_operator" "")
+   (match_operand    1 "comparison_operator" "")
    (match_operand:SI 2 "register_operand" "")
    (match_operand:SI 3 "csky_literal_K_Uh_operand" "")]
   "CSKY_ISA_FEATURE (E2)"
@@ -3330,9 +3251,9 @@
 
 (define_expand "untyped_call"
   [(parallel [(call (match_operand 0 "" "")
-        (const_int 0))
-        (match_operand 1 "" "")
-        (match_operand 2 "" "")])]
+	(const_int 0))
+	(match_operand 1 "" "")
+	(match_operand 2 "" "")])]
   ""
 {
   int i;
@@ -3364,9 +3285,9 @@
   [(set_attr "length" "0")])
 
 (define_insn "*call_value_internal_vs"
-  [(set (match_operand:SF               0 "register_operand"          "=v,v,v")
-        (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
-              (match_operand 2 "" "")))
+  [(set (match_operand:SF	       0 "register_operand"	  "=v,v,v")
+	(call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
+	      (match_operand 2 "" "")))
    (clobber (reg:SI CSKY_LR_REGNUM))]
   "TARGET_HARD_FLOAT_ABI"
   "@
@@ -3378,9 +3299,9 @@
 )
 
 (define_insn "*call_value_internal_vd"
-  [(set (match_operand:DF               0 "register_operand"          "=v,v,v")
-        (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
-              (match_operand 2 "" "")))
+  [(set (match_operand:DF	       0 "register_operand"	  "=v,v,v")
+	(call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
+	      (match_operand 2 "" "")))
    (clobber (reg:SI CSKY_LR_REGNUM))]
   "TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
   "@
@@ -3392,18 +3313,18 @@
 )
 
 (define_insn "*call_value_internal_pic_vs"
-  [(set (match_operand:SF               0 "register_operand"    "=v")
-        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
-                      (match_operand    2 "" "")))
+  [(set (match_operand:SF	       0 "register_operand"    "=v")
+	(call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
+		      (match_operand    2 "" "")))
    (clobber (reg:SI CSKY_LR_REGNUM))]
   "flag_pic && TARGET_HARD_FLOAT_ABI"
   "* return csky_output_call (operands, 1);"
 )
 
 (define_insn "*call_value_internal_pic_vd"
-  [(set (match_operand:DF               0 "register_operand"    "=v")
-        (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
-                      (match_operand    2 "" "")))
+  [(set (match_operand:DF	       0 "register_operand"    "=v")
+	(call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
+		      (match_operand    2 "" "")))
    (clobber (reg:SI CSKY_LR_REGNUM))]
   "flag_pic && TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
   "* return csky_output_call (operands, 1);"
@@ -3894,8 +3815,3 @@
   "CSKY_ISA_FEATURE (E2)"
   "revb\t%0, %1"
 )
-
-
-
-
-
diff --git a/gcc/config/csky/csky_cores.def b/gcc/config/csky/csky_cores.def
index c18fa795051..909c737dd74 100644
--- a/gcc/config/csky/csky_cores.def
+++ b/gcc/config/csky/csky_cores.def
@@ -38,6 +38,8 @@ CSKY_ARCH ("ck807",  ck807,  CK807,
 	   CSKY_ISA_FEAT (CSKY_ISA_CK807) CSKY_ISA_FEAT (CSKY_ISA_DSP))
 CSKY_ARCH ("ck810",  ck810,  CK810,
 	   CSKY_ISA_FEAT (CSKY_ISA_CK810) CSKY_ISA_FEAT (CSKY_ISA_DSP))
+CSKY_ARCH ("ck860",  ck860,  CK860,
+	   CSKY_ISA_FEAT (CSKY_ISA_CK860))
 #endif
 
 
@@ -181,6 +183,12 @@ CSKY_CORE ("ck810ft",  ck810ff,	 ck810ft,  CK810,
 	   CSKY_ISA_FEAT_NONE)
 CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
 	   CSKY_ISA_FEAT_NONE)
+
+/* ck860 Architecture Processors */
+CSKY_CORE("ck860",    ck860,    ck860,    CK860,
+	  CSKY_ISA_FEAT_NONE)
+CSKY_CORE("ck860f",   ck860f,   ck860f,   CK860,
+	  CSKY_ISA_FEAT_NONE)
 #endif
 
 
@@ -196,4 +204,9 @@ CSKY_CORE ("ck810ftv", ck810ftv, ck810ftv, CK810,
 CSKY_FPU ("fpv2_sf",   fpv2_sf,	  CSKY_ISA_FEAT (CSKY_ISA_FPv2_SF))
 CSKY_FPU ("fpv2",      fpv2,	  CSKY_ISA_FEAT (CSKY_ISA_FPv2))
 CSKY_FPU ("fpv2_divd", fpv2_divd, CSKY_ISA_FEAT (CSKY_ISA_FPv2_DIVD))
+
+CSKY_FPU ("fpv3_hf",   fpv3_hf,   CSKY_ISA_FEAT (CSKY_ISA_FPv3_HF))
+CSKY_FPU ("fpv3_hsf",  fpv3_hsf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_HSF))
+CSKY_FPU ("fpv3_sdf",  fpv3_sdf,  CSKY_ISA_FEAT (CSKY_ISA_FPv3_SDF))
+CSKY_FPU ("fpv3",      fpv3,      CSKY_ISA_FEAT (CSKY_ISA_FPv3))
 #endif
diff --git a/gcc/config/csky/csky_insn_fpu.md b/gcc/config/csky/csky_insn_fpu.md
index 700208ebe93..d829b426ab7 100644
--- a/gcc/config/csky/csky_insn_fpu.md
+++ b/gcc/config/csky/csky_insn_fpu.md
@@ -18,528 +18,313 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.  */
 
-;; -------------------------------------------------------------------------
-;; Float Abs instructions
-;; -------------------------------------------------------------------------
+(define_c_enum "unspec" [
+  UNSPEC_FLOOR
+  UNSPEC_CEIL
+  UNSPEC_BTRUNC
+  UNSPEC_RINT
+])
 
-(define_insn "abssf2"
-  [(set (match_operand:SF	  0 "register_operand" "=v,r")
-	(abs:SF (match_operand:SF 1 "register_operand" "v, r")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "@
-    fabss\t%0, %1
-    bclri\t%0, %1, 31")
+(define_c_enum "unspecv" [
+  VUNSPEC_GET_FCR     ; Represent fetch of FCR content.
+  VUNSPEC_SET_FCR     ; Represent assign of FCR content.
+  VUNSPEC_INS_FCR     ; Represent insert of FCR content.
+])
 
-(define_insn "absdf2"
-  [(set (match_operand:DF	  0 "register_operand" "=v")
-	(abs:DF (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fabsd\t%0, %1")
+(define_mode_iterator F3ANY [HF SF DF])
+(define_mode_attr f3t [(HF "16") (SF "32") (DF "64")])
 
+(define_mode_iterator SFDF [SF DF])
+(define_mode_attr f2t [(SF "32") (DF "64")])
 
-;; -------------------------------------------------------------------------
-;; Float Neg instructions
-;; -------------------------------------------------------------------------
+(define_code_iterator FCMPZ [ne ge lt gt le])
+(define_code_attr zero_inst [(ne "nez") (ge "hsz") (lt "ltz") (gt "hz") (le "lsz")])
 
-(define_insn "negsf2"
-  [(set (match_operand:SF	  0 "register_operand" "=v")
-	(neg:SF (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnegs\t%0, %1")
+(define_code_iterator FCMP [ne ge lt])
+(define_code_attr reg_inst [(ne "ne") (ge "hs") (lt "lt")])
 
-(define_insn "negdf2"
-  [(set (match_operand:DF	  0 "register_operand" "=v")
-	(neg:DF (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnegd\t%0, %1")
+(define_code_iterator FIX_SU [fix unsigned_fix])
+(define_code_attr fixsuop [(fix "")  (unsigned_fix "uns")])
+(define_code_attr fixsu   [(fix "s") (unsigned_fix "u")])
 
+(define_code_iterator FLOAT_SU [float unsigned_float])
+(define_code_attr floatsuop [(float "")  (unsigned_float "uns")])
+(define_code_attr floatsu   [(float "s") (unsigned_float "u")])
 
-;; -------------------------------------------------------------------------
-;; Float Sqrt instructions
-;; -------------------------------------------------------------------------
+(define_int_iterator FRM  [UNSPEC_FLOOR
+			   UNSPEC_CEIL UNSPEC_RINT])
 
-(define_insn "sqrtsf2"
-  [(set (match_operand:SF	   0 "register_operand" "=v")
-	(sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fsqrts\t%0, %1")
+(define_int_iterator FRMF [UNSPEC_FLOOR
+			   UNSPEC_CEIL UNSPEC_BTRUNC])
 
-(define_insn "sqrtdf2"
-  [(set (match_operand:DF	   0 "register_operand" "=v")
-	(sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_divd)"
- "fsqrtd\t%0, %1")
+(define_int_attr frm_pattern [(UNSPEC_FLOOR "floor")
+			      (UNSPEC_CEIL "ceil")   (UNSPEC_BTRUNC "btrunc")
+			      (UNSPEC_RINT "rint")])
+
+(define_int_attr rm [(UNSPEC_FLOOR ".rni")
+		     (UNSPEC_CEIL ".rpi")  (UNSPEC_BTRUNC ".rz")
+		     (UNSPEC_RINT "")])
 
 
 ;; -------------------------------------------------------------------------
-;; Float Add instructions
+;; Float mov instructions
 ;; -------------------------------------------------------------------------
 
-(define_insn "addsf3"
-  [(set (match_operand:SF	   0 "register_operand" "=v")
-	(plus:SF (match_operand:SF 1 "register_operand" "v")
-		 (match_operand:SF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fadds\t%0, %1, %2")
+(define_expand "movhf"
+  [(set (match_operand:HF 0 "general_operand" "")
+	(match_operand:HF 1 "general_operand" ""))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "
+  {
+    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
+      {
+	operands[1] = force_reg (HFmode, operands[1]);
+      }
+  }
+")
+
+(define_expand "mov<mode>"
+  [(set (match_operand:SFDF 0 "general_operand" "")
+	(match_operand:SFDF 1 "general_operand" ""))]
+  ""
+  "
+  {
+    if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
+      {
+	operands[1] = force_reg (<MODE>mode, operands[1]);
+      }
+  }
+")
+
+;; Move float value with general register.
+
+(define_insn "*e2_movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
+       (match_operand:SF 1 "general_operand"      " b,r,m,mF,r"))]
+  "CSKY_ISA_FEATURE (E2)
+   && !CSKY_ISA_FEATURE (fpv2_sf)
+   && !CSKY_ISA_FEATURE (fpv3_sf)"
+  "* return csky_output_move (insn, operands, SFmode);"
+ [(set_attr "length" "2,4,4,4,4")
+  (set_attr "type" "alu,alu,load,load,store")]
+)
+
+(define_insn "*e2_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
+       (match_operand:DF 1 "general_operand"      " b,r,m,mF,r"))]
+  "CSKY_ISA_FEATURE (E2)
+   && !CSKY_ISA_FEATURE (fpv2_df)
+   && !CSKY_ISA_FEATURE (fpv3_df)"
+  "* return csky_output_movedouble (operands, DFmode);"
+ [(set_attr "length" "4,8,8,8,8")
+  (set_attr "type" "alu,alu,load,load,store")]
+)
 
-(define_insn "adddf3"
-  [(set (match_operand:DF	   0 "register_operand" "=v")
-	(plus:DF (match_operand:DF 1 "register_operand" "v")
-		 (match_operand:DF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "faddd\t%0, %1, %2")
+(define_insn "*e1_movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
+	(match_operand:SF 1 "general_operand"      " r,m,mF,r"))]
+  "CSKY_ISA_FEATURE (E1)"
+  "* return csky_output_ck801_move (insn, operands, SFmode);"
+  [(set_attr "length" "2,4,4,4")
+   (set_attr "type" "alu,load,load,store")]
+)
 
+(define_insn "*e1_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
+	(match_operand:DF 1 "general_operand"      " r,m,mF,r"))]
+  "CSKY_ISA_FEATURE (E1)"
+  "* return csky_output_ck801_movedouble (operands, DFmode);"
+  [(set_attr "length" "4,8,8,8")
+   (set_attr "type" "alu,load,load,store")]
+)
 
 ;; -------------------------------------------------------------------------
-;; Float Sub instructions
+;; Float Mul instructions
 ;; -------------------------------------------------------------------------
 
-(define_insn "subsf3"
-  [(set (match_operand:SF	    0 "register_operand" "=v")
-	(minus:SF (match_operand:SF 1 "register_operand" "v")
-		  (match_operand:SF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fsubs\t%0, %1, %2")
+(define_expand "mulhf3"
+  [(set (match_operand:HF	    0 "register_operand" "=v")
+	(mult:HF (match_operand:HF   1 "register_operand" "v")
+		 (match_operand:HF   2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
 
-(define_insn "subdf3"
-  [(set (match_operand:DF	    0 "register_operand" "=v")
-	(minus:DF (match_operand:DF 1 "register_operand" "v")
-		  (match_operand:DF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fsubd\t%0, %1, %2")
+(define_expand "mul<mode>3"
+  [(set (match_operand:SFDF	    0 "register_operand" "=v")
+	(mult:SFDF (match_operand:SFDF   1 "register_operand" "v")
+		 (match_operand:SFDF   2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>)
+  || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
 
+(define_expand "fma<mode>4"
+  [(set (match_operand:F3ANY	    0 "register_operand" "=v")
+	(fma:F3ANY (match_operand:F3ANY  1 "register_operand" "v")
+		   (match_operand:F3ANY  2 "register_operand" "v")
+		   (match_operand:F3ANY  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
 
 ;; -------------------------------------------------------------------------
-;; Float Mul instructions
+;; Float ADD SUB NEG ABS instructions
 ;; -------------------------------------------------------------------------
 
-(define_insn "mulsf3"
-  [(set (match_operand:SF	   0 "register_operand" "=v")
-	(mult:SF (match_operand:SF 1 "register_operand" "v")
-		 (match_operand:SF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fmuls\t%0, %1, %2")
-
-(define_insn "muldf3"
-  [(set (match_operand:DF	   0 "register_operand" "=v")
-	(mult:DF (match_operand:DF 1 "register_operand" "v")
-		 (match_operand:DF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fmuld\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmulsf3_1"
-  [(set (match_operand:SF		   0 "register_operand" "=v")
-	(mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
-		 (match_operand:SF	   2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
-  "fnmuls\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmulsf3_2"
-  [(set (match_operand:SF		   0 "register_operand" "=v")
-	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
-			 (match_operand:SF 2 "register_operand" "v"))))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnmuls\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmuldf3_1"
-  [(set (match_operand:DF		   0 "register_operand" "=v")
-	(mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
-		 (match_operand:DF	   2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
- "fnmuld\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmuldf3_2"
-  [(set (match_operand:DF		   0 "register_operand" "=v")
-	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
-			 (match_operand:DF 2 "register_operand" "v"))))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnmuld\t%0, %1, %2")
+(define_expand "addhf3"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(plus:HF (match_operand:HF  1 "register_operand" "")
+		 (match_operand:HF  2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
 
+(define_expand "add<mode>3"
+  [(set (match_operand:SFDF	     0 "register_operand" "")
+	(plus:SFDF (match_operand:SFDF  1 "register_operand" "")
+		   (match_operand:SFDF  2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
-;; -------------------------------------------------------------------------
-;; Float Div instructions
-;; -------------------------------------------------------------------------
+(define_expand "subhf3"
+  [(set (match_operand:HF	    0 "register_operand" "")
+	(minus:HF (match_operand:HF  1 "register_operand" "")
+		  (match_operand:HF  2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
 
-(define_expand "divsf3"
-  [(set (match_operand:SF	  0 "register_operand" "")
-	(div:SF (match_operand:SF 1 "csky_arith_float1_operand" "")
-		(match_operand:SF 2 "register_operand" "")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "")
+(define_expand "sub<mode>3"
+  [(set (match_operand:SFDF	      0 "register_operand" "")
+	(minus:SFDF (match_operand:SFDF  1 "register_operand" "")
+		    (match_operand:SFDF  2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
-(define_insn "*fpuv2_divsf3"
-  [(set (match_operand:SF	  0 "register_operand" "=v")
-	(div:SF (match_operand:SF 1 "register_operand" "v")
-		(match_operand:SF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fdivs\t%0, %1, %2")
-
-(define_insn "*fpuv2_1_divsf3"
-  [(set (match_operand:SF	  0 "register_operand"		"=v")
-	(div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
-		(match_operand:SF 2 "register_operand"		"v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "frecips\t%0, %2")
-
-
-(define_expand "divdf3"
-  [(set (match_operand:DF 0 "register_operand" "")
-	(div:DF (match_operand:DF 1 "csky_arith_float1_operand" "")
-		(match_operand:DF 2 "register_operand" "")))]
-  "CSKY_ISA_FEATURE (fpv2_divd)"
-  "")
+(define_expand "abshf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(abs:HF (match_operand:HF   1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
+
+(define_expand "abs<mode>2"
+  [(set (match_operand:SFDF	     0 "register_operand" "")
+	(abs:SFDF (match_operand:SFDF   1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
+
+(define_expand "neghf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(neg:HF (match_operand:HF   1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
 
-(define_insn "*fpuv2_divdf3"
-  [(set (match_operand:DF	  0 "register_operand" "=v")
-	(div:DF (match_operand:DF 1 "register_operand" "v")
-		(match_operand:DF 2 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_divd)"
-  "fdivd\t%0, %1, %2")
+(define_expand "neg<mode>2"
+  [(set (match_operand:SFDF	   0 "register_operand" "")
+	(neg:SFDF (match_operand:SFDF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
-(define_insn "*fpuv2_1_divdf3"
-  [(set (match_operand:DF	  0 "register_operand"		"=v")
-	(div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
-		(match_operand:DF 2 "register_operand"		"v")))]
-  "CSKY_ISA_FEATURE (fpv2_divd)"
-  "frecipd\t%0, %2")
+(define_expand "sqrthf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(sqrt:HF (match_operand:HF  1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  ""
+)
 
+(define_expand "sqrt<mode>2"
+  [(set (match_operand:SFDF	    0 "register_operand" "")
+	(sqrt:SFDF (match_operand:SFDF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  ""
+)
 
 ;; -------------------------------------------------------------------------
-;; Float add(sub) with mult instructions
+;; Float div instructions
 ;; -------------------------------------------------------------------------
 
-;; vrz <= vrz + vrx * vry
-(define_insn "*fpuv2_fmacs"
-  [(set (match_operand:SF		    0 "register_operand" "=v")
-	(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
-			  (match_operand:SF 2 "register_operand" "v"))
-		 (match_operand:SF	    3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fmacs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fmacd"
-  [(set (match_operand:DF		    0 "register_operand" "=v")
-	(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
-			  (match_operand:DF 2 "register_operand" "v"))
-		 (match_operand:DF	    3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fmacd\t%0, %1, %2")
-
-;; vrz <= vrz - vrx * vry
-(define_insn "*fpuv2_fnmacs"
-  [(set (match_operand:SF		     0 "register_operand" "=v")
-	(minus:SF (match_operand:SF	     1 "register_operand" "0")
-		  (mult:SF (match_operand:SF 2 "register_operand" "v")
-			   (match_operand:SF 3 "register_operand" "v"))))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnmacs\t%0, %2, %3")
-
-(define_insn "*fpuv2_fnmacd"
-  [(set (match_operand:DF		     0 "register_operand" "=v")
-	(minus:DF (match_operand:DF	     1 "register_operand" "0")
-		  (mult:DF (match_operand:DF 2 "register_operand" "v")
-			   (match_operand:DF 3 "register_operand" "v"))))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnmacd\t%0, %2, %3")
-
-;; vrz <= vrx * vry - vrz
-(define_insn "*fpuv2_fmscs"
-  [(set (match_operand:SF		     0 "register_operand" "=v")
-	(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
-			   (match_operand:SF 2 "register_operand" "v"))
-		  (match_operand:SF	     3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fmscd"
-  [(set (match_operand:DF 0 "register_operand" "=v")
-	(minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
-			   (match_operand:DF 2 "register_operand" "v"))
-		  (match_operand:DF 3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fmscd\t%0, %1, %2")
-
-;; vrz = - (vrz + vrx * vry)
-(define_insn "*fpuv2_fnmscs_1"
-  [(set (match_operand:SF			     0 "register_operand" "=v")
-	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
-			   (match_operand:SF	     2 "register_operand" "v"))
-		  (match_operand:SF		     3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscs_2"
-  [(set (match_operand:SF			    0 "register_operand" "=v")
-	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
-				  (match_operand:SF 2 "register_operand" "v"))
-			 (match_operand:SF	    3 "register_operand" "0"))))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fnmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscd_1"
-  [(set (match_operand:DF 0 "register_operand" "=v")
-	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
-			   (match_operand:DF 2 "register_operand" "v"))
-		  (match_operand:DF 3 "register_operand" "0")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnmscd\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscd_2"
-  [(set (match_operand:DF 0 "register_operand" "=v")
-	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
-				  (match_operand:DF 2 "register_operand" "v"))
-			 (match_operand:DF 3 "register_operand" "0"))))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fnmscd\t%0, %1, %2")
+(define_expand "div<mode>3"
+  [(set (match_operand:SFDF	   0 "register_operand" "")
+	(div:SFDF (match_operand:SFDF 1 "csky_arith_float1_operand" "")
+		  (match_operand:SFDF 2 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
 
+(define_expand "divhf3"
+ [(set (match_operand:HF 0 "register_operand" "")
+       (div:HF (match_operand:HF 1 "csky_arith_float1_operand" "")
+	       (match_operand:HF 2 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
 
 ;; -------------------------------------------------------------------------
 ;; Float compare instructions
 ;; -------------------------------------------------------------------------
 
-(define_expand "cbranchsf4"
+(define_expand "cbranch<mode>4"
   [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
-			     [(match_operand:SF 1 "register_operand")
-			      (match_operand:SF 2 "csky_compare_operand_float")])
+			    [(match_operand:SFDF 1 "register_operand")
+			     (match_operand:SFDF 2 "csky_compare_operand_float")])
 			   (label_ref (match_operand 3 ""))
 			   (pc)))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "
-  {
-    enum rtx_code code = GET_CODE (operands[0]);
-    bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
+"CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+"{
+  enum rtx_code code = GET_CODE (operands[0]);
+  bool invert;
 
-    if (invert)
-      emit_jump_insn (gen_csky_jbf (operands[3]));
-    else
-      emit_jump_insn (gen_csky_jbt (operands[3]));
+  invert = csky_emit_compare_float (code, operands[1], operands[2]);
 
-    DONE;
-  }")
-
-(define_insn "*fpuv2_unordered"
-  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
-				  (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpuos\t%0, %1")
-
-(define_insn "*fpuv2_unordered_zero"
-  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
-				  (match_operand:SF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpuos\t%0, %0")
-
-(define_insn "*fpuv2_ne"
-  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpnes\t%0, %1")
-
-(define_insn "*fpuv2_gt"
-  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmplts\t%1, %0")
-
-(define_insn "*fpuv2_ge"
-  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmphss\t%0, %1")
-
-(define_insn "*fpuv2_lt"
-  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmplts\t%0, %1")
-
-(define_insn "*fpuv2_le"
-  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
-			   (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmphss\t%1, %0")
-
-(define_insn "*fpuv2_gez"
-  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand"	   "v")
-			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpzhss\t%0")
-
-(define_insn "*fpuv2_nez"
-  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand"	   "v")
-			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fcmpznes\t%0")
-
-
-(define_expand "cbranchdf4"
-  [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
-			     [(match_operand:DF 1 "register_operand")
-			      (match_operand:DF 2 "csky_compare_operand_float")])
-			   (label_ref (match_operand 3 ""))
-			   (pc)))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "
-  {
-    enum rtx_code code = GET_CODE (operands[0]);
-    bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
+  if (invert)
+    emit_jump_insn (gen_csky_jbf (operands[3]));
+  else
+    emit_jump_insn (gen_csky_jbt (operands[3]));
 
-    if (invert)
-      emit_jump_insn (gen_csky_jbf (operands[3]));
-    else
-      emit_jump_insn (gen_csky_jbt (operands[3]));
+  DONE;
 
-    DONE;
 }")
 
-(define_insn "*fpuv2_dunordered"
-  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
-				  (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpuod\t%0, %1")
-
-(define_insn "*fpuv2_dunordered_zero"
-  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
-				  (match_operand:DF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpuod\t%0, %0")
-
-(define_insn "*fpuv2_dne"
-  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpned\t%0, %1")
-
-(define_insn "*fpuv2_dgt"
-  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpltd\t%1, %0")
-
-(define_insn "*fpuv2_dge"
-  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmphsd\t%0, %1")
-
-(define_insn "*fpuv2_dlt"
-  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpltd\t%0, %1")
-
-(define_insn "*fpuv2_dle"
-  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
-			   (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmphsd\t%1, %0")
-
-(define_insn "*fpuv2_dgez"
-  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand"	   "v")
-			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpzhsd\t%0")
-
-(define_insn "*fpuv2_dnez"
-  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand"	   "v")
-			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fcmpzned\t%0")
-
+(define_expand "cbranchhf4"
+  [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
+			    [(match_operand:HF 1 "register_operand")
+			     (match_operand:HF 2 "csky_compare_operand_float")])
+			   (label_ref (match_operand 3 ""))
+			   (pc)))]
+"CSKY_ISA_FEATURE(fpv3_hf)"
+"{
+  enum rtx_code code = GET_CODE (operands[0]);
+  bool invert;
 
-;; -------------------------------------------------------------------------
-;; Float convert instructions
-;; -------------------------------------------------------------------------
+  invert = csky_emit_compare_float (code, operands[1], operands[2]);
 
-;; DF <- SF
-(define_insn "extendsfdf2"
-  [(set (match_operand:DF		   0 "register_operand" "=v")
-	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fstod\t%0, %1")
+  if (invert)
+    emit_jump_insn (gen_csky_jbf (operands[3]));
+  else
+    emit_jump_insn (gen_csky_jbt (operands[3]));
 
-;; SF <- DF
-(define_insn "truncdfsf2"
-  [(set (match_operand:SF		     0 "register_operand" "=v")
-	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fdtos\t%0, %1")
-
-;; SF <- SI
-(define_insn "floatsisf2"
-  [(set (match_operand:SF	    0 "register_operand" "=v")
-	(float:SF (match_operand:SI 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fsitos\t%0, %1")
-
-;; DF <- SI
-(define_insn "floatsidf2"
-  [(set (match_operand:DF	    0 "register_operand" "=v")
-	(float:DF (match_operand:SI 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fsitod\t%0, %1")
-
-;; SF <- unsigned SI
-(define_insn "floatunssisf2"
-  [(set (match_operand:SF		     0 "register_operand" "=v")
-	(unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fuitos\t%0, %1")
-
-;; DF <- unsigned SI
-(define_insn "floatunssidf2"
-  [(set (match_operand:DF		     0 "register_operand" "=v")
-	(unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fuitod\t%0, %1")
-
-;; SI <- SF
-(define_insn "fix_truncsfsi2"
-  [(set (match_operand:SI	  0 "register_operand" "=v")
-	(fix:SI (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fstosi.rz\t%0, %1")
-
-;; SI <- DF
-(define_insn "fix_truncdfsi2"
-  [(set (match_operand:SI	  0 "register_operand" "=v")
-	(fix:SI (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fdtosi.rz\t%0, %1")
-
-;; unsigned SI <- SF
-(define_insn "fixuns_truncsfsi2"
-  [(set (match_operand:SI		   0 "register_operand" "=v")
-	(unsigned_fix:SI (match_operand:SF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "fstoui.rz\t%0, %1")
-
-;; unsigned SI <- DF
-(define_insn "fixuns_truncdfsi2"
-  [(set (match_operand:SI		   0 "register_operand" "=v")
-	(unsigned_fix:SI (match_operand:DF 1 "register_operand" "v")))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "fdtoui.rz\t%0, %1")
+  DONE;
 
+}")
 
 ;; -------------------------------------------------------------------------
-;; Float mov instructions
+;; Instructions for float cstore
 ;; -------------------------------------------------------------------------
 
-;; Note:  movsf and movdf patterns are in csky.md.
-
-;; cstore SF
-(define_expand "cstoresf4"
+(define_expand "cstore<mode>4"
   [(set (match_operand:SI 0 "register_operand" "")
-	(match_operator	  1 "ordered_comparison_operator"
-	  [(match_operand:SF 2 "register_operand" "")
-	   (match_operand:SF 3 "csky_compare_operand_float" "")]))]
-  "CSKY_ISA_FEATURE (fpv2_sf)"
-  "
-  {
-    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
-					   operands[2], operands[3]);
-    if (invert)
+	(match_operator   1 "csky_float_comparison_operator"
+	  [(match_operand:SFDF 2 "register_operand" "")
+	   (match_operand:SFDF 3 "csky_compare_operand_float" "")]))]
+  "CSKY_ISA_FEATURE (fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "{
+    bool invert;
+
+    invert = csky_emit_compare_float (GET_CODE (operands[1]),
+				 operands[2], operands[3]);
+    if(invert)
       emit_insn (gen_mvcv (operands[0]));
     else
       emit_insn (gen_mvc (operands[0]));
@@ -547,21 +332,91 @@
   }"
 )
 
-;; cstore DF
-(define_expand "cstoredf4"
+(define_expand "cstorehf4"
   [(set (match_operand:SI 0 "register_operand" "")
-	(match_operator 1 "ordered_comparison_operator"
-	  [(match_operand:DF 2 "register_operand" "")
-	   (match_operand:DF 3 "csky_compare_operand_float" "")]))]
-  "CSKY_ISA_FEATURE (fpv2_df)"
-  "
-  {
-    bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
-					   operands[2], operands[3]);
-    if (invert)
+	(match_operator   1 "csky_float_comparison_operator"
+	  [(match_operand:HF 2 "register_operand" "")
+	   (match_operand:HF 3 "csky_compare_operand_float" "")]))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "{
+    bool invert;
+
+    invert = csky_emit_compare_float (GET_CODE (operands[1]),
+				 operands[2], operands[3]);
+    if(invert)
       emit_insn (gen_mvcv (operands[0]));
     else
       emit_insn (gen_mvc (operands[0]));
     DONE;
   }"
 )
+
+;; -------------------------------------------------------------------------
+;; Float convert instructions
+;; -------------------------------------------------------------------------
+
+;; SF <- HF
+(define_expand "extendhfsf2"
+  [(set (match_operand:SF		  0 "register_operand" "")
+	(float_extend:SF (match_operand:HF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; HF <- SF
+(define_expand "truncsfhf2"
+  [(set (match_operand:HF		     0 "register_operand" "")
+	(float_truncate:HF (match_operand:SF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; DF <- SF
+(define_expand "extendsfdf2"
+  [(set (match_operand:DF		  0 "register_operand" "")
+	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
+  "")
+
+;; SF <- DF
+(define_expand "truncdfsf2"
+  [(set (match_operand:SF		    0 "register_operand" "")
+	(float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
+  "")
+
+;; HF <- unsigned SI,SI
+(define_expand "float<floatsuop>sihf2"
+  [(set (match_operand:HF	   0 "register_operand" "")
+	(FLOAT_SU:HF (match_operand:SI 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; DF,SF <- unsigned SI,SI
+(define_expand "float<floatsuop>si<mode>2"
+  [(set (match_operand:SFDF		    0 "register_operand" "")
+	(FLOAT_SU:SFDF (match_operand:SI 1 "register_operand" "")))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
+
+;; DF,SF,HF <- unsigned HI,HI
+;;(define_expand "float<floatsuop>hi<mode>2"
+;;  [(set (match_operand:F3ANY	   0 "register_operand" "")
+;;	(FLOAT_SU:F3ANY (match_operand:HI 1 "register_operand" "")))]
+;;  "CSKY_ISA_FEATURE(fpv3_<mode>) && CSKY_ISA_FEATURE(fpv3_hi)"
+;;  "")
+
+;; unsigned SI,SI <- HF
+(define_expand "fix<fixsuop>_trunchfsi2"
+  [(set (match_operand:SI	    0 "register_operand" "")
+	(FIX_SU:SI (fix:HF (match_operand:HF 1 "register_operand" ""))))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "")
+
+;; unsigned SI,SI <- DF,SF
+(define_expand "fix<fixsuop>_trunc<mode>si2"
+  [(set (match_operand:SI	    0 "register_operand" "")
+	(FIX_SU:SI (fix:SFDF (match_operand:SFDF 1 "register_operand" ""))))]
+  "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "")
+
+(include "csky_insn_fpuv3.md")
+(include "csky_insn_fpuv2.md")
diff --git a/gcc/config/csky/csky_insn_fpuv2.md b/gcc/config/csky/csky_insn_fpuv2.md
new file mode 100644
index 00000000000..0339deedb2e
--- /dev/null
+++ b/gcc/config/csky/csky_insn_fpuv2.md
@@ -0,0 +1,470 @@
+
+;; -------------------------------------------------------------------------
+;; Float Abs instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_abssf2"
+  [(set (match_operand:SF	 0 "register_operand" "=v,a,r")
+	(abs:SF (match_operand:SF 1 "register_operand" "v, 0,r")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "@
+    fabss\t%0, %1
+    bclri\t%0, %1, 31
+    bclri\t%0, %1, 31"
+  [(set_attr "length" "4,2,4")])
+
+(define_insn "*fpuv2_absdf2"
+  [(set (match_operand:DF	 0 "register_operand" "=v")
+	(abs:DF (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fabsd\t%0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Float Neg instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_negsf2"
+  [(set (match_operand:SF	 0 "register_operand" "=v")
+	(neg:SF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnegs\t%0, %1")
+
+(define_insn "*fpuv2_negdf2"
+  [(set (match_operand:DF	 0 "register_operand" "=v")
+	(neg:DF (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnegd\t%0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Float Sqrt instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_sqrtsf2"
+  [(set (match_operand:SF	  0 "register_operand" "=v")
+	(sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fsqrts\t%0, %1")
+
+(define_insn "*fpuv2_sqrtdf2"
+  [(set (match_operand:DF	  0 "register_operand" "=v")
+	(sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_divd)"
+ "fsqrtd\t%0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Float Add instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_addsf3"
+  [(set (match_operand:SF	  0 "register_operand" "=v")
+	(plus:SF (match_operand:SF 1 "register_operand" "v")
+		 (match_operand:SF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fadds\t%0, %1, %2")
+
+(define_insn "*fpuv2_adddf3"
+  [(set (match_operand:DF	  0 "register_operand" "=v")
+	(plus:DF (match_operand:DF 1 "register_operand" "v")
+		 (match_operand:DF 2 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_df)"
+ "faddd\t%0, %1, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float Sub instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_subsf3"
+  [(set (match_operand:SF	   0 "register_operand" "=v")
+	(minus:SF (match_operand:SF 1 "register_operand" "v")
+		  (match_operand:SF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fsubs\t%0, %1, %2")
+
+(define_insn "*fpuv2_subdf3"
+  [(set (match_operand:DF	   0 "register_operand" "=v")
+	(minus:DF (match_operand:DF 1 "register_operand" "v")
+		  (match_operand:DF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fsubd\t%0, %1, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float Mul instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv2_mulsf3"
+  [(set (match_operand:SF	  0 "register_operand" "=v")
+	(mult:SF (match_operand:SF 1 "register_operand" "v")
+		 (match_operand:SF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fmuls\t%0, %1, %2")
+
+(define_insn "*fpv2_muldf3"
+  [(set (match_operand:DF	  0 "register_operand" "=v")
+	(mult:DF (match_operand:DF 1 "register_operand" "v")
+		 (match_operand:DF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fmuld\t%0, %1, %2")
+
+(define_insn "*fpuv2_nmulsf3_1"
+  [(set (match_operand:SF		  0 "register_operand" "=v")
+	(mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
+		 (match_operand:SF	 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
+  "fnmuls\t%0, %1, %2")
+
+(define_insn "*fpuv2_nmulsf3_2"
+  [(set (match_operand:SF		  0 "register_operand" "=v")
+	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
+			 (match_operand:SF 2 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnmuls\t%0, %1, %2")
+
+(define_insn "*fpuv2_nmuldf3_1"
+  [(set (match_operand:DF		  0 "register_operand" "=v")
+	(mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
+		 (match_operand:DF	 2 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
+ "fnmuld\t%0, %1, %2")
+
+(define_insn "*fpuv2_nmuldf3_2"
+  [(set (match_operand:DF		  0 "register_operand" "=v")
+	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
+			 (match_operand:DF 2 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnmuld\t%0, %1, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float Div instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_divsf3"
+  [(set (match_operand:SF	 0 "register_operand" "=v")
+	(div:SF (match_operand:SF 1 "register_operand" "v")
+		(match_operand:SF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fdivs\t%0, %1, %2")
+
+(define_insn "*fpuv2_1_divsf3"
+  [(set (match_operand:SF	 0 "register_operand"	  "=v")
+	(div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
+		(match_operand:SF 2 "register_operand"	  "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "frecips\t%0, %2")
+
+(define_insn "*fpuv2_divdf3"
+  [(set (match_operand:DF	 0 "register_operand" "=v")
+	(div:DF (match_operand:DF 1 "register_operand" "v")
+		(match_operand:DF 2 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_divd)"
+  "fdivd\t%0, %1, %2")
+
+(define_insn "*fpuv2_1_divdf3"
+  [(set (match_operand:DF	 0 "register_operand"	  "=v")
+	(div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
+		(match_operand:DF 2 "register_operand"	  "v")))]
+  "CSKY_ISA_FEATURE (fpv2_divd)"
+  "frecipd\t%0, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float add(sub) with mult instructions
+;; -------------------------------------------------------------------------
+
+;; vrz <= vrz + vrx * vry
+(define_insn "*fpuv2_fmacs"
+  [(set (match_operand:SF		   0 "register_operand" "=v")
+	(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
+			  (match_operand:SF 2 "register_operand" "v"))
+		 (match_operand:SF	  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fmacs\t%0, %1, %2")
+
+(define_insn "*fpuv2_fmacd"
+  [(set (match_operand:DF		   0 "register_operand" "=v")
+	(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
+			  (match_operand:DF 2 "register_operand" "v"))
+		 (match_operand:DF	  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fmacd\t%0, %1, %2")
+
+;; vrz <= vrz - vrx * vry
+(define_insn "*fpuv2_fnmacs"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(minus:SF (match_operand:SF	  1 "register_operand" "0")
+		  (mult:SF (match_operand:SF 2 "register_operand" "v")
+			   (match_operand:SF 3 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnmacs\t%0, %2, %3")
+
+(define_insn "*fpuv2_fnmacd"
+  [(set (match_operand:DF		    0 "register_operand" "=v")
+	(minus:DF (match_operand:DF	  1 "register_operand" "0")
+		  (mult:DF (match_operand:DF 2 "register_operand" "v")
+			   (match_operand:DF 3 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnmacd\t%0, %2, %3")
+
+;; vrz <= vrx * vry - vrz
+(define_insn "*fpuv2_fmscs"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
+			   (match_operand:SF 2 "register_operand" "v"))
+		  (match_operand:SF	  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fmscs\t%0, %1, %2")
+
+(define_insn "*fpuv2_fmscd"
+  [(set (match_operand:DF 0 "register_operand" "=v")
+	(minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
+			   (match_operand:DF 2 "register_operand" "v"))
+		  (match_operand:DF 3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fmscd\t%0, %1, %2")
+
+;; vrz = - (vrz + vrx * vry)
+(define_insn "*fpuv2_fnmscs_1"
+  [(set (match_operand:SF			    0 "register_operand" "=v")
+	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
+			   (match_operand:SF	 2 "register_operand" "v"))
+		  (match_operand:SF		  3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnmscs\t%0, %1, %2")
+
+(define_insn "*fpuv2_fnmscs_2"
+  [(set (match_operand:SF			   0 "register_operand" "=v")
+	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
+				  (match_operand:SF 2 "register_operand" "v"))
+			 (match_operand:SF	  3 "register_operand" "0"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fnmscs\t%0, %1, %2")
+
+(define_insn "*fpuv2_fnmscd_1"
+  [(set (match_operand:DF 0 "register_operand" "=v")
+	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
+			   (match_operand:DF 2 "register_operand" "v"))
+		  (match_operand:DF 3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnmscd\t%0, %1, %2")
+
+(define_insn "*fpuv2_fnmscd_2"
+  [(set (match_operand:DF 0 "register_operand" "=v")
+	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
+				  (match_operand:DF 2 "register_operand" "v"))
+			 (match_operand:DF 3 "register_operand" "0"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fnmscd\t%0, %1, %2")
+
+
+;; -------------------------------------------------------------------------
+;; Float compare instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_unordered"
+  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
+				  (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpuos\t%0, %1")
+
+(define_insn "*fpuv2_unordered_zero"
+  [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
+				  (match_operand:SF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpuos\t%0, %0")
+
+(define_insn "*fpuv2_ne"
+  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpnes\t%0, %1")
+
+(define_insn "*fpuv2_gt"
+  [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmplts\t%1, %0")
+
+(define_insn "*fpuv2_ge"
+  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_sf)"
+ "fcmphss\t%0, %1")
+
+(define_insn "*fpuv2_lt"
+  [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmplts\t%0, %1")
+
+(define_insn "*fpuv2_le"
+  [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
+			   (match_operand:SF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_sf)"
+ "fcmphss\t%1, %0")
+
+(define_insn "*fpuv2_gez"
+  [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand"	  "v")
+			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpzhss\t%0")
+
+(define_insn "*fpuv2_nez"
+  [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand"	  "v")
+			   (match_operand:SF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fcmpznes\t%0")
+
+(define_insn "*fpuv2_dunordered"
+  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
+				  (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpuod\t%0, %1")
+
+(define_insn "*fpuv2_dunordered_zero"
+  [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
+				  (match_operand:DF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpuod\t%0, %0")
+
+(define_insn "*fpuv2_dne"
+  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpned\t%0, %1")
+
+(define_insn "*fpuv2_dgt"
+  [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpltd\t%1, %0")
+
+(define_insn "*fpuv2_dge"
+  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmphsd\t%0, %1")
+
+(define_insn "*fpuv2_dlt"
+  [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE (fpv2_df)"
+ "fcmpltd\t%0, %1")
+
+(define_insn "*fpuv2_dle"
+  [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
+			   (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmphsd\t%1, %0")
+
+(define_insn "*fpuv2_dgez"
+  [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand"	  "v")
+			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
+ "CSKY_ISA_FEATURE (fpv2_df)"
+ "fcmpzhsd\t%0")
+
+(define_insn "*fpuv2_dnez"
+  [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand"	  "v")
+			   (match_operand:DF 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fcmpzned\t%0")
+
+
+;; -------------------------------------------------------------------------
+;; Float convert instructions
+;; -------------------------------------------------------------------------
+
+;; DF <- SF
+(define_insn "*fpuv2_extendsfdf2"
+  [(set (match_operand:DF		  0 "register_operand" "=v")
+	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fstod\t%0, %1")
+
+;; SF <- DF
+(define_insn "*fpuv2_truncdfsf2"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fdtos\t%0, %1")
+
+;; SF <- SI
+(define_insn "*fpuv2_floatsisf2"
+  [(set (match_operand:SF	   0 "register_operand" "=v")
+	(float:SF (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fsitos\t%0, %1")
+
+;; DF <- SI
+(define_insn "*fpuv2_floatsidf2"
+  [(set (match_operand:DF	   0 "register_operand" "=v")
+	(float:DF (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fsitod\t%0, %1")
+
+;; SF <- unsigned SI
+(define_insn "*fpuv2_floatunssisf2"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fuitos\t%0, %1")
+
+;; DF <- unsigned SI
+(define_insn "*fpuv2_floatunssidf2"
+  [(set (match_operand:DF		    0 "register_operand" "=v")
+	(unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fuitod\t%0, %1")
+
+;; SI <- SF
+(define_insn "*fpuv2_fix_truncsfsi2"
+  [(set (match_operand:SI	 0 "register_operand" "=v")
+	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fstosi.rz\t%0, %1")
+
+;; SI <- DF
+(define_insn "*fpuv2_fix_truncdfsi2"
+  [(set (match_operand:SI	 0 "register_operand" "=v")
+	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fdtosi.rz\t%0, %1")
+
+;; unsigned SI <- SF
+(define_insn "*fpuv2_fixuns_truncsfsi2"
+  [(set (match_operand:SI		  0 "register_operand" "=v")
+	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "fstoui.rz\t%0, %1")
+
+;; unsigned SI <- DF
+(define_insn "*fpuv2_fixuns_truncdfsi2"
+  [(set (match_operand:SI		  0 "register_operand" "=v")
+	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "fdtoui.rz\t%0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Float mov instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpuv2_movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v")
+	(match_operand:SF 1 "general_operand"      "r, F,r,v,r,m,v,Q,v,W"))]
+  "CSKY_ISA_FEATURE (fpv2_sf)"
+  "* return csky_output_move(insn, operands, SFmode);"
+)
+
+(define_insn "*fpuv2_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,v,?r,m,r,Q,v,v,v")
+	(match_operand:DF 1 "general_operand"      "r, F,?r,v,r,m,v,Q,v,m"))]
+  "CSKY_ISA_FEATURE (fpv2_df)"
+  "* return csky_output_movedouble(operands, DFmode);"
+  [(set (attr "length")
+	(symbol_ref "get_output_csky_movedouble_length (operands)"))]
+)
diff --git a/gcc/config/csky/csky_insn_fpuv3.md b/gcc/config/csky/csky_insn_fpuv3.md
new file mode 100644
index 00000000000..5fc54049652
--- /dev/null
+++ b/gcc/config/csky/csky_insn_fpuv3.md
@@ -0,0 +1,418 @@
+
+(define_c_enum "unspec" [
+  UNSPEC_MAXNM_F3
+  UNSPEC_MINNM_F3
+])
+
+;; -------------------------------------------------------------------------
+;; Float mov instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_movhf"
+  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v, v")
+	(match_operand:HF 1 "general_operand"      " r,F,r,v,r,m,v,Q,v,W,Dv"))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "*
+  switch (which_alternative)
+    {
+    case 2:
+      return \"fmtvr.16\\t%0, %1\";
+    case 3:
+      return \"fmfvr.16\\t%0, %1\";
+    case 6:
+    case 7:
+    case 9:
+      return fpuv3_output_move(operands);
+    case 8:
+      return \"fmov.16\\t%0, %1\";
+    case 10:
+      return \"fmovi.16\\t%0, %1\";
+    case 1:
+      {
+	long bits;
+	rtx ops[4];
+
+	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), HFmode);
+	ops[0] = operands[0];
+	ops[1] = GEN_INT (bits);
+
+	output_asm_insn (\"lrw\\t%0, %1\", ops);
+	return \"\";
+      }
+    default:
+      return csky_output_move(insn, operands, HFmode);
+    }
+  "
+)
+
+(define_insn "*fpv3_movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v, v")
+	(match_operand:SF 1 "general_operand"      " r,F,r,v,r,m,v,Q,v,W,Dv"))]
+  "CSKY_ISA_FEATURE(fpv3_sf)"
+  "*
+  switch (which_alternative)
+    {
+    case 2:
+      return \"fmtvr.32.1\\t%0, %1\";
+    case 3:
+      return \"fmfvr.32.1\\t%0, %1\";
+    case 6:
+    case 7:
+    case 9:
+      return fpuv3_output_move(operands);
+    case 8:
+      return \"fmov.32\\t%0, %1\";
+    case 10:
+      return \"fmovi.32\\t%0, %1\";
+    default:
+      return csky_output_move(insn, operands, SFmode);
+    }
+  "
+)
+
+(define_insn "*fpv3_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,v,?r,m,r,Q,v,v,v,v")
+	(match_operand:DF 1 "general_operand"      " r,F,?r,v,r,m,v,Q,v,m,Dv"))]
+  "CSKY_ISA_FEATURE(fpv3_df)"
+  "*
+  switch (which_alternative)
+    {
+    case 2:
+      if (TARGET_BIG_ENDIAN)
+	return \"fmtvr.64\\t%0, %R1, %1\";
+      return \"fmtvr.64\\t%0, %1, %R1\";
+    case 3:
+      if (TARGET_BIG_ENDIAN)
+	return \"fmfvr.64\\t%R0, %0, %1\";
+      return \"fmfvr.64\\t%0, %R0, %1\";
+    case 6:
+    case 7:
+    case 9:
+      return fpuv3_output_move(operands);
+    case 8:
+      return \"fmov.64\\t%0, %1\";
+    case 10:
+      return \"fmovi.64\\t%0, %1\";
+    default:
+      return csky_output_movedouble(operands, DFmode);
+    }
+  "
+)
+
+;; -------------------------------------------------------------------------
+;; Float Mul instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_mul<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+		    (match_operand:F3ANY  2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fmul.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float Muladd and mulsub instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_mula<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "+v")
+	(plus:F3ANY (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+				(match_operand:F3ANY  2 "register_operand" " v"))
+		    (match_dup 0)))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_muls<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "+v")
+	(minus:F3ANY (match_dup 0)
+		     (mult:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+				 (match_operand:F3ANY  2 "register_operand" " v"))))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fmuls.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float fmula/fmuls/fnmula/fnmuls instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_fmuls_<mode>4"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(fma:F3ANY (neg:F3ANY (match_operand:F3ANY  1 "register_operand" "v"))
+		   (match_operand:F3ANY   2 "register_operand" "v")
+		   (match_operand:F3ANY   3 "register_operand"  "0")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "ffmuls.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fmula_<mode>4"
+  [(set (match_operand:F3ANY	    0 "register_operand" "=v")
+	(fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+		   (match_operand:F3ANY 2 "register_operand" " v")
+		   (match_operand:F3ANY 3 "register_operand" "0")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "ffmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fnmula_<mode>4"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(neg: F3ANY (fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+			       (match_operand:F3ANY  2 "register_operand" " v")
+			       (match_operand:F3ANY  3 "register_operand" "0"))))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "ffnmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fnmuls_<mode>4"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(fma:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+		   (match_operand:F3ANY  2 "register_operand" " v")
+		   (neg:F3ANY (match_operand:F3ANY  3 "register_operand" "0"))))]
+  "CSKY_ISA_FEATURE(fpv3_sf)"
+  "ffnmuls.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float div/recipe/sqrt instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_div<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(div:F3ANY (match_operand:F3ANY   1 "register_operand" " v")
+		   (match_operand:F3ANY   2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fdiv.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_recip<mode>3"
+  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
+	(div:F3ANY (match_operand:F3ANY  1 "csky_const_float1_operand" " i")
+		   (match_operand:F3ANY  2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "frecip.<f3t>\t%0, %2"
+)
+
+(define_insn "*fpv3_sqrt<mode>2"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(sqrt:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fsqrt.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float fmax/fmin instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "fmax<mode>3"
+  [(set (match_operand:F3ANY		 0 "register_operand" "=v")
+	(unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
+		       (match_operand:F3ANY  2 "register_operand" " v")]
+		      UNSPEC_MAXNM_F3))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fmaxnm.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "fmin<mode>3"
+  [(set (match_operand:F3ANY		 0 "register_operand" "=v")
+	(unspec:F3ANY [(match_operand:F3ANY  1 "register_operand" " v")
+		       (match_operand:F3ANY  2 "register_operand" " v")]
+		      UNSPEC_MINNM_F3))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fminnm.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float compare instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_<zero_inst>_<mode>3"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(FCMPZ:CC (match_operand:F3ANY 0 "register_operand" "v")
+		  (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
+   "CSKY_ISA_FEATURE(fpv3_<mode>)"
+   "fcmp<zero_inst>.<f3t>\t%0"
+)
+
+(define_insn "*fpv3_<reg_inst>_<mode>3"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(FCMP:CC (match_operand:F3ANY 0 "register_operand" "v")
+		 (match_operand:F3ANY 1 "register_operand" "v")))]
+   "CSKY_ISA_FEATURE(fpv3_<mode>)"
+   "fcmp<reg_inst>.<f3t>\t%0, %1"
+)
+
+(define_insn "*fpv3_gt<mode>3"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(gt:CC (match_operand:F3ANY 0 "register_operand" "v")
+	       (match_operand:F3ANY 1 "register_operand" "v")))]
+   "CSKY_ISA_FEATURE(fpv3_<mode>)"
+   "fcmplt.<f3t>\t%1, %0"
+)
+
+(define_insn "*fpv3_le<mode>3"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(le:CC (match_operand:F3ANY 0 "register_operand" "v")
+	       (match_operand:F3ANY 1 "register_operand" "v")))]
+   "CSKY_ISA_FEATURE(fpv3_<mode>)"
+   "fcmphs.<f3t>\t%1, %0"
+)
+
+(define_insn "*fpv3_unordered"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
+		      (match_operand:F3ANY 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fcmpuo.<f3t>\t%0, %1")
+
+(define_insn "*fpv3_unordered_zero"
+  [(set (reg:CC CSKY_CC_REGNUM)
+	(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
+		      (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fcmpuoz.<f3t>\t%0")
+
+;; -------------------------------------------------------------------------
+;; Float ADD instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_add<mode>3"
+  [(set (match_operand:F3ANY	      0 "register_operand" "=v")
+	(plus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+		    (match_operand:F3ANY  2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fadd.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float SUB instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_sub<mode>3"
+  [(set (match_operand:F3ANY	       0 "register_operand" "=v")
+	(minus:F3ANY (match_operand:F3ANY  1 "register_operand" " v")
+		     (match_operand:F3ANY  2 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fsub.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float NEG instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_neg<mode>2"
+  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
+	(neg:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fneg.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float ABS instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_abs<mode>2"
+  [(set (match_operand:F3ANY	     0 "register_operand" "=v")
+	(abs:F3ANY (match_operand:F3ANY  1 "register_operand" " v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fabs.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float common convert instructions
+;; -------------------------------------------------------------------------
+
+;; SF <- HF
+(define_insn "*fpv3_extendhfsf2"
+  [(set (match_operand:SF		  0 "register_operand" "=v")
+	(float_extend:SF (match_operand:HF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "fhtos\t%0, %1")
+
+;; HF <- SF
+(define_insn "*fpv3_truncsfhf2"
+  [(set (match_operand:HF		     0 "register_operand" "=v")
+	(float_truncate:HF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_hf)"
+  "fstoh\t%0, %1")
+
+;; DF <- SF
+(define_insn "*fpv3_extendsfdf2"
+  [(set (match_operand:DF		  0 "register_operand" "=v")
+	(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_df)"
+  "fstod\t%0, %1")
+
+;; SF <- DF
+(define_insn "*fpv3_truncdfsf2"
+  [(set (match_operand:SF		    0 "register_operand" "=v")
+	(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_df)"
+  "fdtos\t%0, %1")
+
+;; DF,SF,HF <- unsigned SI,SI
+(define_insn "*fpv3_float<floatsuop>si<mode>2"
+  [(set (match_operand:F3ANY	   0 "register_operand" "=v")
+	(FLOAT_SU:F3ANY (match_operand:SI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fitof.<floatsu>32.f<f3t>\t%0, %1")
+
+;; HF <- unsigned HI,HI
+(define_insn "*fpv3_float<floatsuop>hihf2"
+  [(set (match_operand:HF	   0 "register_operand" "=v")
+	(FLOAT_SU:HF (match_operand:HI 1 "register_operand" "v")))]
+  "CSKY_ISA_FEATURE(fpv3_hi)
+   && CSKY_ISA_FEATURE(fpv3_hi)"
+  "fitof.<floatsu>16.f16\t%0, %1")
+
+;; unsigned SI,SI <- DF,SF,HF
+(define_insn "*fpv3_fix<fixsuop>_trunc<mode>si2"
+  [(set (match_operand:SI	    0 "register_operand" "=v")
+	(FIX_SU:SI (fix:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fftoi.f<f3t>.<fixsu>32.rz\t%0, %1")
+
+;; conversions need to be rounding to nearest.
+
+(define_insn "l<frm_pattern><fixsuop><mode>si2"
+  [(set (match_operand:SI 0 "register_operand" "=v")
+	(FIX_SU:SI (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")]
+				   FRM)))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fftoi.f<f3t>.<fixsu>32<rm>\t%0, %1"
+)
+
+(define_insn "<frm_pattern><mode>2"
+  [(set (match_operand:F3ANY 0 "register_operand" "=v")
+	(unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")] FRMF))]
+  "CSKY_ISA_FEATURE(fpv3_<mode>)"
+  "fftofi.f<f3t><rm>\t%0, %1"
+)
+
+;; Write Floating-point Control Register.
+(define_insn "csky_setfcrsi"
+  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FCR)]
+  "CSKY_ISA_FEATURE(fcr)"
+  "mtcr\t%0, fcr"
+)
+
+;; Read Floating-point Control Register.
+(define_insn "csky_getfcrsi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FCR))]
+  "CSKY_ISA_FEATURE(fcr)"
+  "mfcr\t%0, fcr"
+)
+
+;; Insert Floating-point Control Register.
+(define_insn "csky_insfcrsi"
+  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
+		     (match_operand:SI 1 "const_int_operand" "i")
+		     (match_operand:SI 2 "const_int_operand" "i")]VUNSPEC_INS_FCR)
+   (clobber (reg: SI 13))]
+  "CSKY_ISA_FEATURE(fcr)"
+  {
+    operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1);
+    return "mfcr\tt1, fcr\n\tins\tt1, %0, %1, %2\n\tmtcr\tt1, fcr";
+  }
+)
diff --git a/gcc/config/csky/csky_isa.def b/gcc/config/csky/csky_isa.def
index e41e241c9c7..c971ccd3430 100644
--- a/gcc/config/csky/csky_isa.def
+++ b/gcc/config/csky/csky_isa.def
@@ -32,6 +32,7 @@ CSKY_ISA (7E10,	 "Extended insns for arch ck810	 from ck807")
 
 /* Special insns */
 CSKY_ISA (div,	  "divide insns")
+CSKY_ISA (fcr,	  "Control the fcr register")
 
 /* Extended insns */
 CSKY_ISA (dsp,	 "Extended insns for DSP")
@@ -42,6 +43,11 @@ CSKY_ISA (fpv2_sf,    "Single precision operations supported")
 CSKY_ISA (fpv2_df,    "Double precision operations supported")
 CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
 
+CSKY_ISA (fpv3_hi,    "half word for fpu convert supported")
+CSKY_ISA (fpv3_hf,    "half precision operations supported")
+CSKY_ISA (fpv3_sf,    "Single precision operations supported")
+CSKY_ISA (fpv3_df,    "Double precision operations supported")
+
 /* Specific insns mode */
 #ifdef	CSKY_ISA_MACRO
 #define CSKY_ISA_CK801	    CSKY_ISA_FEATURE_GET (E1)
@@ -51,6 +57,7 @@ CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
 #define CSKY_ISA_CK803R1    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E3r1)
 #define CSKY_ISA_CK807	    CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E7)
 #define CSKY_ISA_CK810	    CSKY_ISA_CK807, CSKY_ISA_FEATURE_GET (7E10)
+#define CSKY_ISA_CK860      CSKY_ISA_CK810, CSKY_ISA_FEATURE_GET(3E3r1)
 
 #define CSKY_ISA_DSP	    CSKY_ISA_FEATURE_GET (dsp)
 #define CSKY_ISA_DSP2     CSKY_ISA_FEATURE_GET (dsp2)
@@ -58,4 +65,12 @@ CSKY_ISA (fpv2_divd,  "Double precision div operations supported")
 #define CSKY_ISA_FPv2_SF    CSKY_ISA_FEATURE_GET (fpv2_sf)
 #define CSKY_ISA_FPv2	    CSKY_ISA_FPv2_SF, CSKY_ISA_FEATURE_GET (fpv2_df)
 #define CSKY_ISA_FPv2_DIVD  CSKY_ISA_FPv2, CSKY_ISA_FEATURE_GET (fpv2_divd)
+
+#define CSKY_ISA_FPv3_HF    CSKY_ISA_FEATURE_GET (fpv3_hf), \
+                            CSKY_ISA_FEATURE_GET (fpv3_hi)
+#define CSKY_ISA_FPv3_HSF   CSKY_ISA_FPv3_HF, \
+                            CSKY_ISA_FEATURE_GET (fpv3_sf)
+#define CSKY_ISA_FPv3_SDF   CSKY_ISA_FEATURE_GET (fpv3_sf), \
+                            CSKY_ISA_FEATURE_GET (fpv3_df)
+#define CSKY_ISA_FPv3       CSKY_ISA_FPv3_HF, CSKY_ISA_FPv3_SDF
 #endif
diff --git a/gcc/config/csky/csky_tables.opt b/gcc/config/csky/csky_tables.opt
index f7202b23adb..3f7287ffef5 100644
--- a/gcc/config/csky/csky_tables.opt
+++ b/gcc/config/csky/csky_tables.opt
@@ -194,6 +194,12 @@ Enum(csky_processor_type) String(ck810ft) Value( TARGET_CPU_ck810ff)
 EnumValue
 Enum(csky_processor_type) String(ck810ftv) Value( TARGET_CPU_ck810ftv)
 
+EnumValue
+Enum(csky_processor_type) String(ck860) Value( TARGET_CPU_ck860)
+
+EnumValue
+Enum(csky_processor_type) String(ck860f) Value( TARGET_CPU_ck860f)
+
 Enum
 Name(csky_arch) Type(int)
 Known CSKY architectures (for use with the -march= option):
@@ -213,6 +219,9 @@ Enum(csky_arch) String(ck807) Value(3)
 EnumValue
 Enum(csky_arch) String(ck810) Value(4)
 
+EnumValue
+Enum(csky_arch) String(ck860) Value(5)
+
 Enum
 Name(csky_fpu) Type(enum csky_fpu_type)
 Known CSKY FPUs (for use with the -mfpu= option):
@@ -226,5 +235,17 @@ Enum(csky_fpu) String(fpv2) Value(TARGET_FPU_fpv2)
 EnumValue
 Enum(csky_fpu) String(fpv2_divd) Value(TARGET_FPU_fpv2_divd)
 
+EnumValue
+Enum(csky_fpu) String(fpv3_hf) Value(TARGET_FPU_fpv3_hf)
+
+EnumValue
+Enum(csky_fpu) String(fpv3_hsf) Value(TARGET_FPU_fpv3_hsf)
+
+EnumValue
+Enum(csky_fpu) String(fpv3_sdf) Value(TARGET_FPU_fpv3_sdf)
+
+EnumValue
+Enum(csky_fpu) String(fpv3) Value(TARGET_FPU_fpv3)
+
 EnumValue
 Enum(csky_fpu) String(auto) Value(TARGET_FPU_auto)
diff --git a/gcc/config/csky/predicates.md b/gcc/config/csky/predicates.md
index 2aa012ab1f7..d919276e771 100644
--- a/gcc/config/csky/predicates.md
+++ b/gcc/config/csky/predicates.md
@@ -297,5 +297,4 @@
 })
 
 (define_special_predicate "csky_float_comparison_operator"
-  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
-	       unordered,ordered"))
+  (match_code "eq,ne,le,lt,ge,gt,unordered,ordered"))
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 2c67c818da5..5b2b26c22f9 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -2258,6 +2258,14 @@ Vector registers.
 
 @item z
 Stack pointer register (SP).
+
+@item Q
+A memory address which uses a base register with a short offset
+or with a index register with its scale.
+
+@item W
+A memory address which uses a base register with a index register
+with its scale.
 @end table
 
 @ifset INTERNALS
-- 
2.22.0.windows.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-05-24 11:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-30 12:21 [PATCH] C-SKY: Add fpuv3 instructions and CK860 arch Geng Qi
2021-05-24 10:49 ` Xianmiao Qu
2021-05-24 11:32   ` Xianmiao Qu
  -- strict thread matches above, loose matches on Subject: below --
2020-08-27  9:33 gengqi
2020-09-07 11:27 ` Xianmiao Qu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).