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