[PATCH] C-SKY: Add fpuv3 instructions and CK860 arch

Xianmiao Qu xianmiao_qu@c-sky.com
Mon Sep 7 11:27:16 GMT 2020


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


More information about the Gcc-patches mailing list