From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out30-56.freemail.mail.aliyun.com (out30-56.freemail.mail.aliyun.com [115.124.30.56]) by sourceware.org (Postfix) with ESMTPS id B3B95386F44F for ; Thu, 27 Aug 2020 09:34:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B3B95386F44F X-Alimail-AntiSpam: AC=PASS; BC=-1|-1; BR=01201311R181e4; CH=green; DM=||false|; DS=||; FP=0|-1|-1|-1|0|-1|-1|-1; HT=e01f04427; MF=gengqi@linux.alibaba.com; NM=1; PH=DS; RN=4; SR=0; TI=SMTPD_---0U7-RO8m_1598520837; Received: from ITEB-L-PF1LDBR8.hz.ali.com(mailfrom:gengqi@linux.alibaba.com fp:SMTPD_---0U7-RO8m_1598520837) by smtp.aliyun-inc.com(127.0.0.1); Thu, 27 Aug 2020 17:34:42 +0800 From: gengqi To: gengqi@linux.alibaba.com, xianmiao_qu@c-csky.com, gcc-patches@gcc.gnu.org Cc: gengq Subject: [PATCH] C-SKY: Add fpuv3 instructions and CK860 arch Date: Thu, 27 Aug 2020 17:33:17 +0800 Message-Id: <20200827093318.1745-1-gengqi@linux.alibaba.com> X-Mailer: git-send-email 2.22.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-19.4 required=5.0 tests=BAYES_00, ENV_AND_HDR_SPF_MATCH, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY, USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Aug 2020 09:34:58 -0000 From: gengq 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 ;; . */ -;; ------------------------------------------------------------------------- -;; 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" + [(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, 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 "mul3" + [(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_) + || CSKY_ISA_FEATURE(fpv3_)" + "") +(define_expand "fma4" + [(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_)" + "") ;; ------------------------------------------------------------------------- -;; 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 "add3" + [(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_) || CSKY_ISA_FEATURE(fpv3_)" + "" +) -;; ------------------------------------------------------------------------- -;; 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 "sub3" + [(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_) || CSKY_ISA_FEATURE(fpv3_)" + "" +) -(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 "abs2" + [(set (match_operand:SFDF 0 "register_operand" "") + (abs:SFDF (match_operand:SFDF 1 "register_operand" "")))] + "CSKY_ISA_FEATURE(fpv2_) || CSKY_ISA_FEATURE(fpv3_)" + "" +) + +(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 "neg2" + [(set (match_operand:SFDF 0 "register_operand" "") + (neg:SFDF (match_operand:SFDF 1 "register_operand" "")))] + "CSKY_ISA_FEATURE(fpv2_) || CSKY_ISA_FEATURE(fpv3_)" + "" +) -(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 "sqrt2" + [(set (match_operand:SFDF 0 "register_operand" "") + (sqrt:SFDF (match_operand:SFDF 1 "register_operand" "")))] + "CSKY_ISA_FEATURE(fpv2_) || CSKY_ISA_FEATURE(fpv3_)" + "" +) ;; ------------------------------------------------------------------------- -;; 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 "div3" + [(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_) || CSKY_ISA_FEATURE(fpv3_)" + "") +(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 "cbranch4" [(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_) || CSKY_ISA_FEATURE(fpv3_)" +"{ + 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 "cstore4" [(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_) || CSKY_ISA_FEATURE(fpv3_)" + "{ + 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 "floatsihf2" + [(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 "floatsi2" + [(set (match_operand:SFDF 0 "register_operand" "") + (FLOAT_SU:SFDF (match_operand:SI 1 "register_operand" "")))] + "CSKY_ISA_FEATURE(fpv2_) || CSKY_ISA_FEATURE(fpv3_)" + "") + +;; DF,SF,HF <- unsigned HI,HI +;;(define_expand "floathi2" +;; [(set (match_operand:F3ANY 0 "register_operand" "") +;; (FLOAT_SU:F3ANY (match_operand:HI 1 "register_operand" "")))] +;; "CSKY_ISA_FEATURE(fpv3_) && CSKY_ISA_FEATURE(fpv3_hi)" +;; "") + +;; unsigned SI,SI <- HF +(define_expand "fix_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_truncsi2" + [(set (match_operand:SI 0 "register_operand" "") + (FIX_SU:SI (fix:SFDF (match_operand:SFDF 1 "register_operand" ""))))] + "CSKY_ISA_FEATURE(fpv2_) || CSKY_ISA_FEATURE(fpv3_)" + "") + +(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_mul3" + [(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_)" + "fmul.\t%0, %1, %2" +) + +;; ------------------------------------------------------------------------- +;; Float Muladd and mulsub instructions +;; ------------------------------------------------------------------------- + +(define_insn "*fpv3_mula3" + [(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_)" + "fmula.\t%0, %1, %2" +) + +(define_insn "*fpv3_muls3" + [(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_)" + "fmuls.\t%0, %1, %2" +) + +;; ------------------------------------------------------------------------- +;; Float fmula/fmuls/fnmula/fnmuls instructions +;; ------------------------------------------------------------------------- + +(define_insn "*fpv3_fmuls_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_)" + "ffmuls.\t%0, %1, %2" +) + +(define_insn "*fpv3_fmula_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_)" + "ffmula.\t%0, %1, %2" +) + +(define_insn "*fpv3_fnmula_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_)" + "ffnmula.\t%0, %1, %2" +) + +(define_insn "*fpv3_fnmuls_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.\t%0, %1, %2" +) + +;; ------------------------------------------------------------------------- +;; Float div/recipe/sqrt instructions +;; ------------------------------------------------------------------------- + +(define_insn "*fpv3_div3" + [(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_)" + "fdiv.\t%0, %1, %2" +) + +(define_insn "*fpv3_recip3" + [(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_)" + "frecip.\t%0, %2" +) + +(define_insn "*fpv3_sqrt2" + [(set (match_operand:F3ANY 0 "register_operand" "=v") + (sqrt:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))] + "CSKY_ISA_FEATURE(fpv3_)" + "fsqrt.\t%0, %1" +) + +;; ------------------------------------------------------------------------- +;; Float fmax/fmin instructions +;; ------------------------------------------------------------------------- + +(define_insn "fmax3" + [(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_)" + "fmaxnm.\t%0, %1, %2" +) + +(define_insn "fmin3" + [(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_)" + "fminnm.\t%0, %1, %2" +) + +;; ------------------------------------------------------------------------- +;; Float compare instructions +;; ------------------------------------------------------------------------- + +(define_insn "*fpv3__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_)" + "fcmp.\t%0" +) + +(define_insn "*fpv3__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_)" + "fcmp.\t%0, %1" +) + +(define_insn "*fpv3_gt3" + [(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_)" + "fcmplt.\t%1, %0" +) + +(define_insn "*fpv3_le3" + [(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_)" + "fcmphs.\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_)" + "fcmpuo.\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_)" + "fcmpuoz.\t%0") + +;; ------------------------------------------------------------------------- +;; Float ADD instructions +;; ------------------------------------------------------------------------- + +(define_insn "*fpv3_add3" + [(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_)" + "fadd.\t%0, %1, %2" +) + +;; ------------------------------------------------------------------------- +;; Float SUB instructions +;; ------------------------------------------------------------------------- + +(define_insn "*fpv3_sub3" + [(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_)" + "fsub.\t%0, %1, %2" +) + +;; ------------------------------------------------------------------------- +;; Float NEG instructions +;; ------------------------------------------------------------------------- + +(define_insn "*fpv3_neg2" + [(set (match_operand:F3ANY 0 "register_operand" "=v") + (neg:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))] + "CSKY_ISA_FEATURE(fpv3_)" + "fneg.\t%0, %1" +) + +;; ------------------------------------------------------------------------- +;; Float ABS instructions +;; ------------------------------------------------------------------------- + +(define_insn "*fpv3_abs2" + [(set (match_operand:F3ANY 0 "register_operand" "=v") + (abs:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))] + "CSKY_ISA_FEATURE(fpv3_)" + "fabs.\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_floatsi2" + [(set (match_operand:F3ANY 0 "register_operand" "=v") + (FLOAT_SU:F3ANY (match_operand:SI 1 "register_operand" "v")))] + "CSKY_ISA_FEATURE(fpv3_)" + "fitof.32.f\t%0, %1") + +;; HF <- unsigned HI,HI +(define_insn "*fpv3_floathihf2" + [(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.16.f16\t%0, %1") + +;; unsigned SI,SI <- DF,SF,HF +(define_insn "*fpv3_fix_truncsi2" + [(set (match_operand:SI 0 "register_operand" "=v") + (FIX_SU:SI (fix:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))))] + "CSKY_ISA_FEATURE(fpv3_)" + "fftoi.f.32.rz\t%0, %1") + +;; conversions need to be rounding to nearest. + +(define_insn "lsi2" + [(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_)" + "fftoi.f.32\t%0, %1" +) + +(define_insn "2" + [(set (match_operand:F3ANY 0 "register_operand" "=v") + (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")] FRMF))] + "CSKY_ISA_FEATURE(fpv3_)" + "fftofi.f\t%0, %1" +) + +;; Write Floating-point Control Register. +(define_insn "csky_setfcrsi" + [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FCR)] + "CSKY_ISA_FEATURE(fcr)" + "mtcr\t%0, fcr" +) + +;; Read Floating-point Control Register. +(define_insn "csky_getfcrsi" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FCR))] + "CSKY_ISA_FEATURE(fcr)" + "mfcr\t%0, fcr" +) + +;; Insert Floating-point Control Register. +(define_insn "csky_insfcrsi" + [(unspec_volatile [(match_operand:SI 0 "register_operand" "r") + (match_operand:SI 1 "const_int_operand" "i") + (match_operand:SI 2 "const_int_operand" "i")]VUNSPEC_INS_FCR) + (clobber (reg: SI 13))] + "CSKY_ISA_FEATURE(fcr)" + { + operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1); + return "mfcr\tt1, fcr\n\tins\tt1, %0, %1, %2\n\tmtcr\tt1, fcr"; + } +) diff --git a/gcc/config/csky/csky_isa.def b/gcc/config/csky/csky_isa.def index e41e241c9c7..c971ccd3430 100644 --- a/gcc/config/csky/csky_isa.def +++ b/gcc/config/csky/csky_isa.def @@ -32,6 +32,7 @@ CSKY_ISA (7E10, "Extended insns for arch ck810 from ck807") /* Special insns */ CSKY_ISA (div, "divide insns") +CSKY_ISA (fcr, "Control the fcr register") /* Extended insns */ CSKY_ISA (dsp, "Extended insns for DSP") @@ -42,6 +43,11 @@ CSKY_ISA (fpv2_sf, "Single precision operations supported") CSKY_ISA (fpv2_df, "Double precision operations supported") CSKY_ISA (fpv2_divd, "Double precision div operations supported") +CSKY_ISA (fpv3_hi, "half word for fpu convert supported") +CSKY_ISA (fpv3_hf, "half precision operations supported") +CSKY_ISA (fpv3_sf, "Single precision operations supported") +CSKY_ISA (fpv3_df, "Double precision operations supported") + /* Specific insns mode */ #ifdef CSKY_ISA_MACRO #define CSKY_ISA_CK801 CSKY_ISA_FEATURE_GET (E1) @@ -51,6 +57,7 @@ CSKY_ISA (fpv2_divd, "Double precision div operations supported") #define CSKY_ISA_CK803R1 CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E3r1) #define CSKY_ISA_CK807 CSKY_ISA_CK803, CSKY_ISA_FEATURE_GET (3E7) #define CSKY_ISA_CK810 CSKY_ISA_CK807, CSKY_ISA_FEATURE_GET (7E10) +#define CSKY_ISA_CK860 CSKY_ISA_CK810, CSKY_ISA_FEATURE_GET(3E3r1) #define CSKY_ISA_DSP CSKY_ISA_FEATURE_GET (dsp) #define CSKY_ISA_DSP2 CSKY_ISA_FEATURE_GET (dsp2) @@ -58,4 +65,12 @@ CSKY_ISA (fpv2_divd, "Double precision div operations supported") #define CSKY_ISA_FPv2_SF CSKY_ISA_FEATURE_GET (fpv2_sf) #define CSKY_ISA_FPv2 CSKY_ISA_FPv2_SF, CSKY_ISA_FEATURE_GET (fpv2_df) #define CSKY_ISA_FPv2_DIVD CSKY_ISA_FPv2, CSKY_ISA_FEATURE_GET (fpv2_divd) + +#define CSKY_ISA_FPv3_HF CSKY_ISA_FEATURE_GET (fpv3_hf), \ + CSKY_ISA_FEATURE_GET (fpv3_hi) +#define CSKY_ISA_FPv3_HSF CSKY_ISA_FPv3_HF, \ + CSKY_ISA_FEATURE_GET (fpv3_sf) +#define CSKY_ISA_FPv3_SDF CSKY_ISA_FEATURE_GET (fpv3_sf), \ + CSKY_ISA_FEATURE_GET (fpv3_df) +#define CSKY_ISA_FPv3 CSKY_ISA_FPv3_HF, CSKY_ISA_FPv3_SDF #endif diff --git a/gcc/config/csky/csky_tables.opt b/gcc/config/csky/csky_tables.opt index f7202b23adb..3f7287ffef5 100644 --- a/gcc/config/csky/csky_tables.opt +++ b/gcc/config/csky/csky_tables.opt @@ -194,6 +194,12 @@ Enum(csky_processor_type) String(ck810ft) Value( TARGET_CPU_ck810ff) EnumValue Enum(csky_processor_type) String(ck810ftv) Value( TARGET_CPU_ck810ftv) +EnumValue +Enum(csky_processor_type) String(ck860) Value( TARGET_CPU_ck860) + +EnumValue +Enum(csky_processor_type) String(ck860f) Value( TARGET_CPU_ck860f) + Enum Name(csky_arch) Type(int) Known CSKY architectures (for use with the -march= option): @@ -213,6 +219,9 @@ Enum(csky_arch) String(ck807) Value(3) EnumValue Enum(csky_arch) String(ck810) Value(4) +EnumValue +Enum(csky_arch) String(ck860) Value(5) + Enum Name(csky_fpu) Type(enum csky_fpu_type) Known CSKY FPUs (for use with the -mfpu= option): @@ -226,5 +235,17 @@ Enum(csky_fpu) String(fpv2) Value(TARGET_FPU_fpv2) EnumValue Enum(csky_fpu) String(fpv2_divd) Value(TARGET_FPU_fpv2_divd) +EnumValue +Enum(csky_fpu) String(fpv3_hf) Value(TARGET_FPU_fpv3_hf) + +EnumValue +Enum(csky_fpu) String(fpv3_hsf) Value(TARGET_FPU_fpv3_hsf) + +EnumValue +Enum(csky_fpu) String(fpv3_sdf) Value(TARGET_FPU_fpv3_sdf) + +EnumValue +Enum(csky_fpu) String(fpv3) Value(TARGET_FPU_fpv3) + EnumValue Enum(csky_fpu) String(auto) Value(TARGET_FPU_auto) diff --git a/gcc/config/csky/predicates.md b/gcc/config/csky/predicates.md index 2aa012ab1f7..d919276e771 100644 --- a/gcc/config/csky/predicates.md +++ b/gcc/config/csky/predicates.md @@ -297,5 +297,4 @@ }) (define_special_predicate "csky_float_comparison_operator" - (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu, - unordered,ordered")) + (match_code "eq,ne,le,lt,ge,gt,unordered,ordered")) diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 2c67c818da5..5b2b26c22f9 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -2258,6 +2258,14 @@ Vector registers. @item z Stack pointer register (SP). + +@item Q +A memory address which uses a base register with a short offset +or with a index register with its scale. + +@item W +A memory address which uses a base register with a index register +with its scale. @end table @ifset INTERNALS -- 2.22.0.windows.1