(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"
"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)")))
--- /dev/null
+/* Float modes. */
+FLOAT_MODE (HF, 2, ieee_half_format); /* Half-precision floating point */
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);
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 */
/* 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,
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. */
builtin_define ("__CSKY_FPUV2__");
}
+ if (TARGET_SUPPORT_FPV3)
+ {
+ builtin_define ("__csky_fpuv3__");
+ builtin_define ("__CSKY_FPUV3__");
+ }
+
if (TARGET_ELRW)
{
builtin_define ("__csky_elrw__");
* Storage Layout *
******************************************************************/
-
#undef TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE \
default_promote_function_mode_always_promote
#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 *
#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);
Mfix *minipool_barrier;
/* Allow GC scanning of the minipool obstack. */
+
static void
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)
{
(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)
}
/* Emit constant pools for -mconstpool. */
+
static void
csky_emit_constant_pools (void)
{
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)
{
/* Implement TARGET_LIBCALL_VALUE. */
+
static rtx
csky_libcall_value (machine_mode mode,
const_rtx libcall ATTRIBUTE_UNUSED)
/* 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)
{
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)
{
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;
}
/* Implement TARGET_HARD_REGNO_NREGS. */
+
static unsigned int
csky_hard_regno_nregs (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)
{
/* 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,
/* 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)
{
/* 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,
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",
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);
{
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)
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;
if (!base)
base = op;
else if (!index)
- index = op;
+ {
+ index = op;
+ scale = 1;
+ }
else
return false;
break;
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;
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;
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)
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:
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:
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:
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:
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
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. */
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)
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)
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)
{
/* 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)
{
/* 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)
{
/* Return true if X is an address form involving a symbol or label ref. */
+
bool
csky_symbolic_address_p (rtx x)
{
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);
/* Implement LEGITIMATE_PIC_OPERAND_P. */
+
bool
csky_legitimate_pic_operand_p (rtx x)
{
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;
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;
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;
return false;
}
/* Verify disp operand. */
- else if (addr.disp)
+ else if (addr.disp && constraint[0] == 'Q')
{
rtx disp = addr.disp;
return false;
}
- return true;
+ else if (constraint[0] == 'Q')
+ /* Single reg is valid for 'Q'. */
+ return true;
+
+ return false;
}
}
}
-/* 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,
}
}
+/* 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
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 ();
}
/* 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)
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)
{
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)
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));
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"
#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)
(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)
/* 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) \
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
******************************************************************/
-#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.
/* 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
/* 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 \
"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. */
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 }
/* 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. */
(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)
(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.
(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)"
(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)"
(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;
""
[(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
)
(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"
"@
)
(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);"
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
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
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
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>. */
-;; -------------------------------------------------------------------------
-;; Float Abs instructions
-;; -------------------------------------------------------------------------
+(define_c_enum "unspec" [
+ UNSPEC_FLOOR
+ UNSPEC_CEIL
+ UNSPEC_BTRUNC
+ UNSPEC_RINT
+])
-(define_insn "abssf2"
- [(set (match_operand:SF 0 "register_operand" "=v,r")
- (abs:SF (match_operand:SF 1 "register_operand" "v, r")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "@
- fabss\t%0, %1
- bclri\t%0, %1, 31")
+(define_c_enum "unspecv" [
+ VUNSPEC_GET_FCR ; Represent fetch of FCR content.
+ VUNSPEC_SET_FCR ; Represent assign of FCR content.
+ VUNSPEC_INS_FCR ; Represent insert of FCR content.
+])
-(define_insn "absdf2"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (abs:DF (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fabsd\t%0, %1")
+(define_mode_iterator F3ANY [HF SF DF])
+(define_mode_attr f3t [(HF "16") (SF "32") (DF "64")])
+(define_mode_iterator SFDF [SF DF])
+(define_mode_attr f2t [(SF "32") (DF "64")])
-;; -------------------------------------------------------------------------
-;; Float Neg instructions
-;; -------------------------------------------------------------------------
+(define_code_iterator FCMPZ [ne ge lt gt le])
+(define_code_attr zero_inst [(ne "nez") (ge "hsz") (lt "ltz") (gt "hz") (le "lsz")])
-(define_insn "negsf2"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (neg:SF (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fnegs\t%0, %1")
+(define_code_iterator FCMP [ne ge lt])
+(define_code_attr reg_inst [(ne "ne") (ge "hs") (lt "lt")])
-(define_insn "negdf2"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (neg:DF (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fnegd\t%0, %1")
+(define_code_iterator FIX_SU [fix unsigned_fix])
+(define_code_attr fixsuop [(fix "") (unsigned_fix "uns")])
+(define_code_attr fixsu [(fix "s") (unsigned_fix "u")])
+(define_code_iterator FLOAT_SU [float unsigned_float])
+(define_code_attr floatsuop [(float "") (unsigned_float "uns")])
+(define_code_attr floatsu [(float "s") (unsigned_float "u")])
-;; -------------------------------------------------------------------------
-;; Float Sqrt instructions
-;; -------------------------------------------------------------------------
+(define_int_iterator FRM [UNSPEC_FLOOR
+ UNSPEC_CEIL UNSPEC_RINT])
-(define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (sqrt:SF (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fsqrts\t%0, %1")
+(define_int_iterator FRMF [UNSPEC_FLOOR
+ UNSPEC_CEIL UNSPEC_BTRUNC])
-(define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (sqrt:DF (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_divd)"
- "fsqrtd\t%0, %1")
+(define_int_attr frm_pattern [(UNSPEC_FLOOR "floor")
+ (UNSPEC_CEIL "ceil") (UNSPEC_BTRUNC "btrunc")
+ (UNSPEC_RINT "rint")])
+
+(define_int_attr rm [(UNSPEC_FLOOR ".rni")
+ (UNSPEC_CEIL ".rpi") (UNSPEC_BTRUNC ".rz")
+ (UNSPEC_RINT "")])
;; -------------------------------------------------------------------------
-;; Float Add instructions
+;; Float mov instructions
;; -------------------------------------------------------------------------
-(define_insn "addsf3"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (plus:SF (match_operand:SF 1 "register_operand" "v")
- (match_operand:SF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fadds\t%0, %1, %2")
+(define_expand "movhf"
+ [(set (match_operand:HF 0 "general_operand" "")
+ (match_operand:HF 1 "general_operand" ""))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "
+ {
+ if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
+ {
+ operands[1] = force_reg (HFmode, operands[1]);
+ }
+ }
+")
+
+(define_expand "mov<mode>"
+ [(set (match_operand:SFDF 0 "general_operand" "")
+ (match_operand:SFDF 1 "general_operand" ""))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>)
+ || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "
+ {
+ if (GET_CODE(operands[0]) == MEM && can_create_pseudo_p ())
+ {
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+ }
+ }
+")
+
+;; Move float value with general register.
+
+(define_insn "*e2_movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m")
+ (match_operand:SF 1 "general_operand" " b,r,m,mF,r"))]
+ "CSKY_ISA_FEATURE (E2)
+ && !CSKY_ISA_FEATURE (fpv2_sf)
+ && !CSKY_ISA_FEATURE (fpv3_sf)"
+ "* return csky_output_move (insn, operands, SFmode);"
+ [(set_attr "length" "2,4,4,4,4")
+ (set_attr "type" "alu,alu,load,load,store")]
+)
+
+(define_insn "*e2_movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m")
+ (match_operand:DF 1 "general_operand" " b,r,m,mF,r"))]
+ "CSKY_ISA_FEATURE (E2)
+ && !CSKY_ISA_FEATURE (fpv2_df)
+ && !CSKY_ISA_FEATURE (fpv3_df)"
+ "* return csky_output_movedouble (operands, DFmode);"
+ [(set_attr "length" "4,8,8,8,8")
+ (set_attr "type" "alu,alu,load,load,store")]
+)
-(define_insn "adddf3"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (plus:DF (match_operand:DF 1 "register_operand" "v")
- (match_operand:DF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "faddd\t%0, %1, %2")
+(define_insn "*e1_movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m")
+ (match_operand:SF 1 "general_operand" " r,m,mF,r"))]
+ "CSKY_ISA_FEATURE (E1)"
+ "* return csky_output_ck801_move (insn, operands, SFmode);"
+ [(set_attr "length" "2,4,4,4")
+ (set_attr "type" "alu,load,load,store")]
+)
+(define_insn "*e1_movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m")
+ (match_operand:DF 1 "general_operand" " r,m,mF,r"))]
+ "CSKY_ISA_FEATURE (E1)"
+ "* return csky_output_ck801_movedouble (operands, DFmode);"
+ [(set_attr "length" "4,8,8,8")
+ (set_attr "type" "alu,load,load,store")]
+)
;; -------------------------------------------------------------------------
-;; Float Sub instructions
+;; Float Mul instructions
;; -------------------------------------------------------------------------
-(define_insn "subsf3"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (minus:SF (match_operand:SF 1 "register_operand" "v")
- (match_operand:SF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fsubs\t%0, %1, %2")
+(define_expand "mulhf3"
+ [(set (match_operand:HF 0 "register_operand" "=v")
+ (mult:HF (match_operand:HF 1 "register_operand" "v")
+ (match_operand:HF 2 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
-(define_insn "subdf3"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (minus:DF (match_operand:DF 1 "register_operand" "v")
- (match_operand:DF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fsubd\t%0, %1, %2")
+(define_expand "mul<mode>3"
+ [(set (match_operand:SFDF 0 "register_operand" "=v")
+ (mult:SFDF (match_operand:SFDF 1 "register_operand" "v")
+ (match_operand:SFDF 2 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>)
+ || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "")
+(define_expand "fma<mode>4"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (fma:F3ANY (match_operand:F3ANY 1 "register_operand" "v")
+ (match_operand:F3ANY 2 "register_operand" "v")
+ (match_operand:F3ANY 3 "register_operand" "0")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "")
;; -------------------------------------------------------------------------
-;; Float Mul instructions
+;; Float ADD SUB NEG ABS instructions
;; -------------------------------------------------------------------------
-(define_insn "mulsf3"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (mult:SF (match_operand:SF 1 "register_operand" "v")
- (match_operand:SF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fmuls\t%0, %1, %2")
-
-(define_insn "muldf3"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (mult:DF (match_operand:DF 1 "register_operand" "v")
- (match_operand:DF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fmuld\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmulsf3_1"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
- (match_operand:SF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf) && !flag_rounding_math"
- "fnmuls\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmulsf3_2"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
- (match_operand:SF 2 "register_operand" "v"))))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fnmuls\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmuldf3_1"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
- (match_operand:DF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df) && !flag_rounding_math"
- "fnmuld\t%0, %1, %2")
-
-(define_insn "*fpuv2_nmuldf3_2"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
- (match_operand:DF 2 "register_operand" "v"))))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fnmuld\t%0, %1, %2")
+(define_expand "addhf3"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (plus:HF (match_operand:HF 1 "register_operand" "")
+ (match_operand:HF 2 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ ""
+)
+
+(define_expand "add<mode>3"
+ [(set (match_operand:SFDF 0 "register_operand" "")
+ (plus:SFDF (match_operand:SFDF 1 "register_operand" "")
+ (match_operand:SFDF 2 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ ""
+)
+(define_expand "subhf3"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (minus:HF (match_operand:HF 1 "register_operand" "")
+ (match_operand:HF 2 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ ""
+)
-;; -------------------------------------------------------------------------
-;; Float Div instructions
-;; -------------------------------------------------------------------------
+(define_expand "sub<mode>3"
+ [(set (match_operand:SFDF 0 "register_operand" "")
+ (minus:SFDF (match_operand:SFDF 1 "register_operand" "")
+ (match_operand:SFDF 2 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ ""
+)
-(define_expand "divsf3"
- [(set (match_operand:SF 0 "register_operand" "")
- (div:SF (match_operand:SF 1 "csky_arith_float1_operand" "")
- (match_operand:SF 2 "register_operand" "")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "")
+(define_expand "abshf2"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (abs:HF (match_operand:HF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ ""
+)
-(define_insn "*fpuv2_divsf3"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (div:SF (match_operand:SF 1 "register_operand" "v")
- (match_operand:SF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fdivs\t%0, %1, %2")
-
-(define_insn "*fpuv2_1_divsf3"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (div:SF (match_operand:SF 1 "csky_const_float1_operand" "i")
- (match_operand:SF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "frecips\t%0, %2")
-
-
-(define_expand "divdf3"
- [(set (match_operand:DF 0 "register_operand" "")
- (div:DF (match_operand:DF 1 "csky_arith_float1_operand" "")
- (match_operand:DF 2 "register_operand" "")))]
- "CSKY_ISA_FEATURE (fpv2_divd)"
- "")
+(define_expand "abs<mode>2"
+ [(set (match_operand:SFDF 0 "register_operand" "")
+ (abs:SFDF (match_operand:SFDF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ ""
+)
-(define_insn "*fpuv2_divdf3"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (div:DF (match_operand:DF 1 "register_operand" "v")
- (match_operand:DF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_divd)"
- "fdivd\t%0, %1, %2")
+(define_expand "neghf2"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (neg:HF (match_operand:HF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ ""
+)
-(define_insn "*fpuv2_1_divdf3"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (div:DF (match_operand:DF 1 "csky_const_float1_operand" "i")
- (match_operand:DF 2 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_divd)"
- "frecipd\t%0, %2")
+(define_expand "neg<mode>2"
+ [(set (match_operand:SFDF 0 "register_operand" "")
+ (neg:SFDF (match_operand:SFDF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ ""
+)
+(define_expand "sqrthf2"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (sqrt:HF (match_operand:HF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ ""
+)
+
+(define_expand "sqrt<mode>2"
+ [(set (match_operand:SFDF 0 "register_operand" "")
+ (sqrt:SFDF (match_operand:SFDF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ ""
+)
;; -------------------------------------------------------------------------
-;; Float add(sub) with mult instructions
+;; Float div instructions
;; -------------------------------------------------------------------------
-;; vrz <= vrz + vrx * vry
-(define_insn "*fpuv2_fmacs"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
- (match_operand:SF 2 "register_operand" "v"))
- (match_operand:SF 3 "register_operand" "0")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fmacs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fmacd"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
- (match_operand:DF 2 "register_operand" "v"))
- (match_operand:DF 3 "register_operand" "0")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fmacd\t%0, %1, %2")
-
-;; vrz <= vrz - vrx * vry
-(define_insn "*fpuv2_fnmacs"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (minus:SF (match_operand:SF 1 "register_operand" "0")
- (mult:SF (match_operand:SF 2 "register_operand" "v")
- (match_operand:SF 3 "register_operand" "v"))))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fnmacs\t%0, %2, %3")
-
-(define_insn "*fpuv2_fnmacd"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (minus:DF (match_operand:DF 1 "register_operand" "0")
- (mult:DF (match_operand:DF 2 "register_operand" "v")
- (match_operand:DF 3 "register_operand" "v"))))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fnmacd\t%0, %2, %3")
-
-;; vrz <= vrx * vry - vrz
-(define_insn "*fpuv2_fmscs"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
- (match_operand:SF 2 "register_operand" "v"))
- (match_operand:SF 3 "register_operand" "0")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fmscd"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
- (match_operand:DF 2 "register_operand" "v"))
- (match_operand:DF 3 "register_operand" "0")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fmscd\t%0, %1, %2")
-
-;; vrz = - (vrz + vrx * vry)
-(define_insn "*fpuv2_fnmscs_1"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "%v"))
- (match_operand:SF 2 "register_operand" "v"))
- (match_operand:SF 3 "register_operand" "0")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fnmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscs_2"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "v")
- (match_operand:SF 2 "register_operand" "v"))
- (match_operand:SF 3 "register_operand" "0"))))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fnmscs\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscd_1"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "%v"))
- (match_operand:DF 2 "register_operand" "v"))
- (match_operand:DF 3 "register_operand" "0")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fnmscd\t%0, %1, %2")
-
-(define_insn "*fpuv2_fnmscd_2"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "v")
- (match_operand:DF 2 "register_operand" "v"))
- (match_operand:DF 3 "register_operand" "0"))))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fnmscd\t%0, %1, %2")
+(define_expand "div<mode>3"
+ [(set (match_operand:SFDF 0 "register_operand" "")
+ (div:SFDF (match_operand:SFDF 1 "csky_arith_float1_operand" "")
+ (match_operand:SFDF 2 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "")
+(define_expand "divhf3"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (div:HF (match_operand:HF 1 "csky_arith_float1_operand" "")
+ (match_operand:HF 2 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
;; -------------------------------------------------------------------------
;; Float compare instructions
;; -------------------------------------------------------------------------
-(define_expand "cbranchsf4"
+(define_expand "cbranch<mode>4"
[(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
- [(match_operand:SF 1 "register_operand")
- (match_operand:SF 2 "csky_compare_operand_float")])
+ [(match_operand:SFDF 1 "register_operand")
+ (match_operand:SFDF 2 "csky_compare_operand_float")])
(label_ref (match_operand 3 ""))
(pc)))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "
- {
- enum rtx_code code = GET_CODE (operands[0]);
- bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
+"CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+"{
+ enum rtx_code code = GET_CODE (operands[0]);
+ bool invert;
- if (invert)
- emit_jump_insn (gen_csky_jbf (operands[3]));
- else
- emit_jump_insn (gen_csky_jbt (operands[3]));
+ invert = csky_emit_compare_float (code, operands[1], operands[2]);
- DONE;
- }")
-
-(define_insn "*fpuv2_unordered"
- [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmpuos\t%0, %1")
-
-(define_insn "*fpuv2_unordered_zero"
- [(set (reg:CC 33) (unordered:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "csky_const_float0_operand" "i")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmpuos\t%0, %0")
-
-(define_insn "*fpuv2_ne"
- [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmpnes\t%0, %1")
-
-(define_insn "*fpuv2_gt"
- [(set (reg:CC 33) (gt:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmplts\t%1, %0")
-
-(define_insn "*fpuv2_ge"
- [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmphss\t%0, %1")
-
-(define_insn "*fpuv2_lt"
- [(set (reg:CC 33) (lt:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmplts\t%0, %1")
-
-(define_insn "*fpuv2_le"
- [(set (reg:CC 33) (le:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmphss\t%1, %0")
-
-(define_insn "*fpuv2_gez"
- [(set (reg:CC 33) (ge:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "csky_const_float0_operand" "i")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmpzhss\t%0")
-
-(define_insn "*fpuv2_nez"
- [(set (reg:CC 33) (ne:CC (match_operand:SF 0 "register_operand" "v")
- (match_operand:SF 1 "csky_const_float0_operand" "i")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fcmpznes\t%0")
-
-
-(define_expand "cbranchdf4"
- [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
- [(match_operand:DF 1 "register_operand")
- (match_operand:DF 2 "csky_compare_operand_float")])
- (label_ref (match_operand 3 ""))
- (pc)))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "
- {
- enum rtx_code code = GET_CODE (operands[0]);
- bool invert = csky_emit_compare_float (code, operands[1], operands[2]);
+ if (invert)
+ emit_jump_insn (gen_csky_jbf (operands[3]));
+ else
+ emit_jump_insn (gen_csky_jbt (operands[3]));
- if (invert)
- emit_jump_insn (gen_csky_jbf (operands[3]));
- else
- emit_jump_insn (gen_csky_jbt (operands[3]));
+ DONE;
- DONE;
}")
-(define_insn "*fpuv2_dunordered"
- [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpuod\t%0, %1")
-
-(define_insn "*fpuv2_dunordered_zero"
- [(set (reg:CC 33) (unordered:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "csky_const_float0_operand" "i")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpuod\t%0, %0")
-
-(define_insn "*fpuv2_dne"
- [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpned\t%0, %1")
-
-(define_insn "*fpuv2_dgt"
- [(set (reg:CC 33) (gt:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpltd\t%1, %0")
-
-(define_insn "*fpuv2_dge"
- [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmphsd\t%0, %1")
-
-(define_insn "*fpuv2_dlt"
- [(set (reg:CC 33) (lt:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpltd\t%0, %1")
-
-(define_insn "*fpuv2_dle"
- [(set (reg:CC 33) (le:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmphsd\t%1, %0")
-
-(define_insn "*fpuv2_dgez"
- [(set (reg:CC 33) (ge:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "csky_const_float0_operand" "i")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpzhsd\t%0")
-
-(define_insn "*fpuv2_dnez"
- [(set (reg:CC 33) (ne:CC (match_operand:DF 0 "register_operand" "v")
- (match_operand:DF 1 "csky_const_float0_operand" "i")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fcmpzned\t%0")
+(define_expand "cbranchhf4"
+ [(set (pc) (if_then_else (match_operator 0 "csky_float_comparison_operator"
+ [(match_operand:HF 1 "register_operand")
+ (match_operand:HF 2 "csky_compare_operand_float")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+"CSKY_ISA_FEATURE(fpv3_hf)"
+"{
+ enum rtx_code code = GET_CODE (operands[0]);
+ bool invert;
+ invert = csky_emit_compare_float (code, operands[1], operands[2]);
-;; -------------------------------------------------------------------------
-;; Float convert instructions
-;; -------------------------------------------------------------------------
+ if (invert)
+ emit_jump_insn (gen_csky_jbf (operands[3]));
+ else
+ emit_jump_insn (gen_csky_jbt (operands[3]));
-;; DF <- SF
-(define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fstod\t%0, %1")
-
-;; SF <- DF
-(define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fdtos\t%0, %1")
-
-;; SF <- SI
-(define_insn "floatsisf2"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (float:SF (match_operand:SI 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fsitos\t%0, %1")
-
-;; DF <- SI
-(define_insn "floatsidf2"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (float:DF (match_operand:SI 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fsitod\t%0, %1")
-
-;; SF <- unsigned SI
-(define_insn "floatunssisf2"
- [(set (match_operand:SF 0 "register_operand" "=v")
- (unsigned_float:SF (match_operand:SI 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fuitos\t%0, %1")
-
-;; DF <- unsigned SI
-(define_insn "floatunssidf2"
- [(set (match_operand:DF 0 "register_operand" "=v")
- (unsigned_float:DF (match_operand:SI 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fuitod\t%0, %1")
-
-;; SI <- SF
-(define_insn "fix_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "=v")
- (fix:SI (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fstosi.rz\t%0, %1")
-
-;; SI <- DF
-(define_insn "fix_truncdfsi2"
- [(set (match_operand:SI 0 "register_operand" "=v")
- (fix:SI (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fdtosi.rz\t%0, %1")
-
-;; unsigned SI <- SF
-(define_insn "fixuns_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "=v")
- (unsigned_fix:SI (match_operand:SF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "fstoui.rz\t%0, %1")
-
-;; unsigned SI <- DF
-(define_insn "fixuns_truncdfsi2"
- [(set (match_operand:SI 0 "register_operand" "=v")
- (unsigned_fix:SI (match_operand:DF 1 "register_operand" "v")))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "fdtoui.rz\t%0, %1")
+ DONE;
+}")
;; -------------------------------------------------------------------------
-;; Float mov instructions
+;; Instructions for float cstore
;; -------------------------------------------------------------------------
-;; Note: movsf and movdf patterns are in csky.md.
-
-;; cstore SF
-(define_expand "cstoresf4"
+(define_expand "cstore<mode>4"
[(set (match_operand:SI 0 "register_operand" "")
- (match_operator 1 "ordered_comparison_operator"
- [(match_operand:SF 2 "register_operand" "")
- (match_operand:SF 3 "csky_compare_operand_float" "")]))]
- "CSKY_ISA_FEATURE (fpv2_sf)"
- "
- {
- bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
- operands[2], operands[3]);
- if (invert)
+ (match_operator 1 "csky_float_comparison_operator"
+ [(match_operand:SFDF 2 "register_operand" "")
+ (match_operand:SFDF 3 "csky_compare_operand_float" "")]))]
+ "CSKY_ISA_FEATURE (fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "{
+ bool invert;
+
+ invert = csky_emit_compare_float (GET_CODE (operands[1]),
+ operands[2], operands[3]);
+ if(invert)
emit_insn (gen_mvcv (operands[0]));
else
emit_insn (gen_mvc (operands[0]));
}"
)
-;; cstore DF
-(define_expand "cstoredf4"
+(define_expand "cstorehf4"
[(set (match_operand:SI 0 "register_operand" "")
- (match_operator 1 "ordered_comparison_operator"
- [(match_operand:DF 2 "register_operand" "")
- (match_operand:DF 3 "csky_compare_operand_float" "")]))]
- "CSKY_ISA_FEATURE (fpv2_df)"
- "
- {
- bool invert = csky_emit_compare_float (GET_CODE (operands[1]),
- operands[2], operands[3]);
- if (invert)
+ (match_operator 1 "csky_float_comparison_operator"
+ [(match_operand:HF 2 "register_operand" "")
+ (match_operand:HF 3 "csky_compare_operand_float" "")]))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "{
+ bool invert;
+
+ invert = csky_emit_compare_float (GET_CODE (operands[1]),
+ operands[2], operands[3]);
+ if(invert)
emit_insn (gen_mvcv (operands[0]));
else
emit_insn (gen_mvc (operands[0]));
DONE;
}"
)
+
+;; -------------------------------------------------------------------------
+;; Float convert instructions
+;; -------------------------------------------------------------------------
+
+;; SF <- HF
+(define_expand "extendhfsf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float_extend:SF (match_operand:HF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
+
+;; HF <- SF
+(define_expand "truncsfhf2"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (float_truncate:HF (match_operand:SF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
+
+;; DF <- SF
+(define_expand "extendsfdf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
+ "")
+
+;; SF <- DF
+(define_expand "truncdfsf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_df) || CSKY_ISA_FEATURE(fpv3_df)"
+ "")
+
+;; HF <- unsigned SI,SI
+(define_expand "float<floatsuop>sihf2"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (FLOAT_SU:HF (match_operand:SI 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
+
+;; DF,SF <- unsigned SI,SI
+(define_expand "float<floatsuop>si<mode>2"
+ [(set (match_operand:SFDF 0 "register_operand" "")
+ (FLOAT_SU:SFDF (match_operand:SI 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "")
+
+;; HF <- unsigned HI,HI
+(define_expand "float<floatsuop>hihf2"
+ [(set (match_operand:HF 0 "register_operand" "")
+ (FLOAT_SU:HF (match_operand:HI 1 "register_operand" "")))]
+ "CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
+
+;; unsigned SI,SI <- HF
+(define_expand "fix<fixsuop>_trunchfsi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (FIX_SU:SI (fix:HF (match_operand:HF 1 "register_operand" ""))))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "")
+
+;; unsigned SI,SI <- DF,SF
+(define_expand "fix<fixsuop>_trunc<mode>si2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (FIX_SU:SI (fix:SFDF (match_operand:SFDF 1 "register_operand" ""))))]
+ "CSKY_ISA_FEATURE(fpv2_<mode>) || CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "")
+
+(include "csky_insn_fpuv3.md")
+(include "csky_insn_fpuv2.md")
--- /dev/null
+
+;; -------------------------------------------------------------------------
+;; 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)"))]
+)
--- /dev/null
+
+(define_c_enum "unspec" [
+ UNSPEC_MAXNM_F3
+ UNSPEC_MINNM_F3
+])
+
+;; -------------------------------------------------------------------------
+;; Float mov instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_movhf"
+ [(set (match_operand:HF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v, v")
+ (match_operand:HF 1 "general_operand" " r,F,r,v,r,m,v,Q,v,W,Dv"))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "*
+ switch (which_alternative)
+ {
+ case 2:
+ return \"fmtvr.16\\t%0, %1\";
+ case 3:
+ return \"fmfvr.16\\t%0, %1\";
+ case 6:
+ case 7:
+ case 9:
+ return fpuv3_output_move(operands);
+ case 8:
+ return \"fmov.16\\t%0, %1\";
+ case 10:
+ return \"fmovi.16\\t%0, %1\";
+ case 1:
+ {
+ long bits;
+ rtx ops[4];
+
+ bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), HFmode);
+ ops[0] = operands[0];
+ ops[1] = GEN_INT (bits);
+
+ output_asm_insn (\"lrw\\t%0, %1\", ops);
+ return \"\";
+ }
+ default:
+ return csky_output_move(insn, operands, HFmode);
+ }
+ "
+)
+
+(define_insn "*fpv3_movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r, r,m,v,r,Q,v,v,v, v")
+ (match_operand:SF 1 "general_operand" " r,m,mF,r,r,v,v,Q,v,W,Dv"))]
+ "CSKY_ISA_FEATURE(fpv3_sf)"
+ "*
+ switch (which_alternative)
+ {
+ case 4:
+ return \"fmtvr.32.1\\t%0, %1\";
+ case 5:
+ return \"fmfvr.32.1\\t%0, %1\";
+ case 6:
+ case 7:
+ case 9:
+ return fpuv3_output_move(operands);
+ case 8:
+ return \"fmov.32\\t%0, %1\";
+ case 10:
+ return \"fmovi.32\\t%0, %1\";
+ default:
+ return csky_output_move(insn, operands, SFmode);
+ }
+ "
+)
+
+(define_insn "*fpv3_movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, r,m,v,?r,Q,v,v,v, v")
+ (match_operand:DF 1 "general_operand" " r,m,mF,r,?r,v,v,Q,v,m,Dv"))]
+ "CSKY_ISA_FEATURE(fpv3_df)"
+ "*
+ switch (which_alternative)
+ {
+ case 4:
+ if (TARGET_BIG_ENDIAN)
+ return \"fmtvr.64\\t%0, %R1, %1\";
+ return \"fmtvr.64\\t%0, %1, %R1\";
+ case 5:
+ if (TARGET_BIG_ENDIAN)
+ return \"fmfvr.64\\t%R0, %0, %1\";
+ return \"fmfvr.64\\t%0, %R0, %1\";
+ case 6:
+ case 7:
+ case 9:
+ return fpuv3_output_move(operands);
+ case 8:
+ return \"fmov.64\\t%0, %1\";
+ case 10:
+ return \"fmovi.64\\t%0, %1\";
+ default:
+ return csky_output_movedouble(operands, DFmode);
+ }
+ "
+)
+
+;; -------------------------------------------------------------------------
+;; Float Mul instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_mul<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (mult:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fmul.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float Muladd and mulsub instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_mula<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "+v")
+ (plus:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v"))
+ (match_dup 0)))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_muls<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "+v")
+ (minus:F3ANY (match_dup 0)
+ (mult:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v"))))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fmuls.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float fmula/fmuls/fnmula/fnmuls instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_fmuls_<mode>4"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (fma:F3ANY (neg:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))
+ (match_operand:F3ANY 2 "register_operand" "v")
+ (match_operand:F3ANY 3 "register_operand" "0")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "ffmuls.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fmula_<mode>4"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")
+ (match_operand:F3ANY 3 "register_operand" "0")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "ffmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fnmula_<mode>4"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (neg: F3ANY (fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")
+ (match_operand:F3ANY 3 "register_operand" "0"))))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "ffnmula.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_fnmuls_<mode>4"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")
+ (neg:F3ANY (match_operand:F3ANY 3 "register_operand" "0"))))]
+ "CSKY_ISA_FEATURE(fpv3_sf)"
+ "ffnmuls.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float div/recipe/sqrt instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_div<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (div:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fdiv.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "*fpv3_recip<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (div:F3ANY (match_operand:F3ANY 1 "csky_const_float1_operand" " i")
+ (match_operand:F3ANY 2 "register_operand" " v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "frecip.<f3t>\t%0, %2"
+)
+
+(define_insn "*fpv3_sqrt<mode>2"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (sqrt:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fsqrt.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float fmax/fmin instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "fmax<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")]
+ UNSPEC_MAXNM_F3))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fmaxnm.<f3t>\t%0, %1, %2"
+)
+
+(define_insn "fmin<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")]
+ UNSPEC_MINNM_F3))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fminnm.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float compare instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_<zero_inst>_<mode>3"
+ [(set (reg:CC CSKY_CC_REGNUM)
+ (FCMPZ:CC (match_operand:F3ANY 0 "register_operand" "v")
+ (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fcmp<zero_inst>.<f3t>\t%0"
+)
+
+(define_insn "*fpv3_<reg_inst>_<mode>3"
+ [(set (reg:CC CSKY_CC_REGNUM)
+ (FCMP:CC (match_operand:F3ANY 0 "register_operand" "v")
+ (match_operand:F3ANY 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fcmp<reg_inst>.<f3t>\t%0, %1"
+)
+
+(define_insn "*fpv3_gt<mode>3"
+ [(set (reg:CC CSKY_CC_REGNUM)
+ (gt:CC (match_operand:F3ANY 0 "register_operand" "v")
+ (match_operand:F3ANY 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fcmplt.<f3t>\t%1, %0"
+)
+
+(define_insn "*fpv3_le<mode>3"
+ [(set (reg:CC CSKY_CC_REGNUM)
+ (le:CC (match_operand:F3ANY 0 "register_operand" "v")
+ (match_operand:F3ANY 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fcmphs.<f3t>\t%1, %0"
+)
+
+(define_insn "*fpv3_unordered"
+ [(set (reg:CC CSKY_CC_REGNUM)
+ (unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
+ (match_operand:F3ANY 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fcmpuo.<f3t>\t%0, %1")
+
+(define_insn "*fpv3_unordered_zero"
+ [(set (reg:CC CSKY_CC_REGNUM)
+ (unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
+ (match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fcmpuoz.<f3t>\t%0")
+
+;; -------------------------------------------------------------------------
+;; Float ADD instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_add<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (plus:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fadd.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float SUB instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_sub<mode>3"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (minus:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
+ (match_operand:F3ANY 2 "register_operand" " v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fsub.<f3t>\t%0, %1, %2"
+)
+
+;; -------------------------------------------------------------------------
+;; Float NEG instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_neg<mode>2"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (neg:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fneg.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float ABS instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "*fpv3_abs<mode>2"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (abs:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fabs.<f3t>\t%0, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; Float common convert instructions
+;; -------------------------------------------------------------------------
+
+;; SF <- HF
+(define_insn "*fpv3_extendhfsf2"
+ [(set (match_operand:SF 0 "register_operand" "=v")
+ (float_extend:SF (match_operand:HF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "fhtos\t%0, %1")
+
+;; HF <- SF
+(define_insn "*fpv3_truncsfhf2"
+ [(set (match_operand:HF 0 "register_operand" "=v")
+ (float_truncate:HF (match_operand:SF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_hf)"
+ "fstoh\t%0, %1")
+
+;; DF <- SF
+(define_insn "*fpv3_extendsfdf2"
+ [(set (match_operand:DF 0 "register_operand" "=v")
+ (float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_df)"
+ "fstod\t%0, %1")
+
+;; SF <- DF
+(define_insn "*fpv3_truncdfsf2"
+ [(set (match_operand:SF 0 "register_operand" "=v")
+ (float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_df)"
+ "fdtos\t%0, %1")
+
+;; DF,SF,HF <- unsigned SI,SI
+(define_insn "*fpv3_float<floatsuop>si<mode>2"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (FLOAT_SU:F3ANY (match_operand:SI 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fitof.<floatsu>32.f<f3t>\t%0, %1")
+
+;; HF <- unsigned HI,HI
+(define_insn "*fpv3_float<floatsuop>hihf2"
+ [(set (match_operand:HF 0 "register_operand" "=v")
+ (FLOAT_SU:HF (match_operand:HI 1 "register_operand" "v")))]
+ "CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
+ "fitof.<floatsu>16.f16\t%0, %1")
+
+;; unsigned SI,SI <- DF,SF,HF
+(define_insn "*fpv3_fix<fixsuop>_trunc<mode>si2"
+ [(set (match_operand:SI 0 "register_operand" "=v")
+ (FIX_SU:SI (fix:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fftoi.f<f3t>.<fixsu>32.rz\t%0, %1")
+
+;; -------------------------------------------------------------------------
+;; Float complex convert instructions
+;; -------------------------------------------------------------------------
+
+;; Fixed point to floating point conversions.
+
+;(define_insn "*combine_fcvt_fixed16_<mode>"
+; [(set (match_operand:F3ANY 0 "register_operand" "=v")
+; (mult:F3ANY (float:F3ANY (match_operand:HI 1 "register_operand" "0"))
+; (match_operand 2
+; "const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
+; "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
+; && CSKY_ISA_FEATURE(fpv3_hi)"
+; "fxtof.s16.f<f3t>\t%0, %1, %v2")
+;
+;(define_insn "*combine_fcvt_fixed32_<mode>"
+; [(set (match_operand:F3ANY 0 "register_operand" "=v")
+; (mult:F3ANY (float:F3ANY (match_operand:SI 1 "register_operand" "0"))
+; (match_operand 2
+; "const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
+; "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
+; "fxtof.s32.f<f3t>\t%0, %1, %v2")
+;
+;(define_insn "*combine_fcvt_unfixed16_<mode>"
+; [(set (match_operand:F3ANY 0 "register_operand" "=v")
+; (mult:F3ANY (unsigned_float:F3ANY (match_operand:HI 1 "register_operand" "0"))
+; (match_operand 2
+; "const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
+; "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
+; && CSKY_ISA_FEATURE(fpv3_hi)"
+; "fxtof.u16.f<f3t>\t%0, %1, %v2")
+;
+;(define_insn "*combine_fcvt_unfixed32_<mode>"
+; [(set (match_operand:F3ANY 0 "register_operand" "=v")
+; (mult:F3ANY (unsigned_float:F3ANY (match_operand:SI 1 "register_operand" "0"))
+; (match_operand 2
+; "const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
+; "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
+; "fxtof.u32.f<f3t>\t%0, %1, %v2")
+
+;; Floating point to fixed point conversions.
+
+;(define_insn "*combine_fcvt<mode>_fixed16"
+; [(set (match_operand:HI 0 "register_operand" "=v")
+; (fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
+; (match_operand 2
+; "const_double_fcvt_power_of_two_hq" "Du")))))]
+; "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
+; && CSKY_ISA_FEATURE(fpv3_hi)"
+; "fftox.f<f3t>.s16\t%0, %1, %v2"
+; )
+;
+;(define_insn "*combine_fcvt<mode>_fixed32"
+; [(set (match_operand:SI 0 "register_operand" "=v")
+; (fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
+; (match_operand 2
+; "const_double_fcvt_power_of_two_sq" "Du")))))]
+; "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
+; "fftox.f<f3t>.s32\t%0, %1, %v2"
+; )
+;
+;(define_insn "*combine_fcvt<mode>_unfixed16"
+; [(set (match_operand:HI 0 "register_operand" "=v")
+; (unsigned_fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
+; (match_operand 2
+; "const_double_fcvt_power_of_two_hq" "Du")))))]
+; "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math
+; && CSKY_ISA_FEATURE(fpv3_hi)"
+; "fftox.f<f3t>.u16\t%0, %1, %v2"
+; )
+;
+;(define_insn "*combine_fcvt<mode>_unfixed32"
+; [(set (match_operand:SI 0 "register_operand" "=v")
+; (unsigned_fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
+; (match_operand 2
+; "const_double_fcvt_power_of_two_sq" "Du")))))]
+; "CSKY_ISA_FEATURE(fpv3_<mode>) && !flag_rounding_math"
+; "fftox.f<f3t>.u32\t%0, %1, %v2"
+; )
+
+;; conversions need to be rounding to nearest.
+
+(define_insn "l<frm_pattern><fixsuop><mode>si2"
+ [(set (match_operand:SI 0 "register_operand" "=v")
+ (FIX_SU:SI (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")]
+ FRM)))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fftoi.f<f3t>.<fixsu>32<rm>\t%0, %1"
+)
+
+(define_insn "<frm_pattern><mode>2"
+ [(set (match_operand:F3ANY 0 "register_operand" "=v")
+ (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")] FRMF))]
+ "CSKY_ISA_FEATURE(fpv3_<mode>)"
+ "fftofi.f<f3t><rm>\t%0, %1"
+)
+
+;; Write Floating-point Control Register.
+(define_insn "csky_setfcrsi"
+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FCR)]
+ "CSKY_ISA_FEATURE(fcr)"
+ "mtcr\t%0, fcr"
+)
+
+;; Read Floating-point Control Register.
+(define_insn "csky_getfcrsi"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FCR))]
+ "CSKY_ISA_FEATURE(fcr)"
+ "mfcr\t%0, fcr"
+)
+
+;; Insert Floating-point Control Register.
+(define_insn "csky_insfcrsi"
+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "const_int_operand" "i")
+ (match_operand:SI 2 "const_int_operand" "i")]VUNSPEC_INS_FCR)
+ (clobber (reg: SI 13))]
+ "CSKY_ISA_FEATURE(fcr)"
+ {
+ operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1);
+ return "mfcr\tt1, fcr\n\tins\tt1, %0, %1, %2\n\tmtcr\tt1, fcr";
+ }
+)
/* Special insns */
CSKY_ISA (div, "divide insns")
+CSKY_ISA (fcr, "Control the fcr register")
/* Extended insns */
CSKY_ISA (dsp, "Extended insns for DSP")
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)
#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
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):
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):
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)
})
(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"))
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
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
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
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
@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