[ARC] Add single/double IEEE precission FPU support.
gcc/ 2016-02-16 Claudiu Zissulescu <claziss@synopsys.com> * config/arc/arc-modes.def (CC_FPU, CC_FPU_UNEQ): New modes. * config/arc/arc-opts.h (FPU_SP, FPU_SF, FPU_SC, FPU_SD, FPU_DP) (FPU_DF, FPU_DC, FPU_DD, FXP_DP): Define. * config/arc/arc.c (arc_init): Check FPU options. (get_arc_condition_code): Handle new CC_FPU* modes. (arc_select_cc_mode): Likewise. (arc_conditional_register_usage): Allow 64 bit datum into even-odd register pair only. Allow access for ARCv2 accumulator. (gen_compare_reg): Whenever we have FPU support use FPU compare instructions. (arc_reorg): Don't generate brcc insns when FPU compare instructions are involved. * config/arc/arc.h (TARGET_DPFP): Add TARGET_FP_DPAX condition. (TARGET_OPTFPE): Add condition when ARC EM can use optimized floating point emulation. (ACC_REG_FIRST, ACC_REG_LAST, ACCL_REGNO, ACCH_REGNO): Define. (REVERSE_CONDITION): Add new CC_FPU* modes. (TARGET_FP_SP_BASE): Define. (TARGET_FP_DP_BASE): Likewise. (TARGET_FP_SP_FUSED): Likewise. (TARGET_FP_DP_FUSED): Likewise. (TARGET_FP_SP_CONV): Likewise. (TARGET_FP_DP_CONV): Likewise. (TARGET_FP_SP_SQRT): Likewise. (TARGET_FP_DP_SQRT): Likewise. (TARGET_FP_DP_AX): Likewise. * config/arc/arc.md (ARCV2_ACC): New constant. (type): New fpu type attribute. (SDF): Conditional iterator. (cstore<mode>, cbranch<mode>): Change expand condition. (addsf3, subsf3, mulsf3, adddf3, subdf3, muldf3): New expands, handles FPU/FPX cases as well. * config/arc/arc.opt (mfpu): New option. * config/arc/fpx.md (addsf3_fpx, subsf3_fpx, mulsf3_fpx): Renamed. (adddf3, muldf3, subdf3): Removed. * config/arc/predicates.md (proper_comparison_operator): Recognize CC_FPU* modes. * config/arc/fpu.md: New file. * doc/invoke.texi (ARC Options): Document mfpu option. From-SVN: r233451
This commit is contained in:
parent
d5b1a52eec
commit
8f3304d019
@ -1,3 +1,46 @@
|
||||
2016-02-16 Claudiu Zissulescu <claziss@synopsys.com>
|
||||
|
||||
* config/arc/arc-modes.def (CC_FPU, CC_FPU_UNEQ): New modes.
|
||||
* config/arc/arc-opts.h (FPU_SP, FPU_SF, FPU_SC, FPU_SD, FPU_DP)
|
||||
(FPU_DF, FPU_DC, FPU_DD, FXP_DP): Define.
|
||||
* config/arc/arc.c (arc_init): Check FPU options.
|
||||
(get_arc_condition_code): Handle new CC_FPU* modes.
|
||||
(arc_select_cc_mode): Likewise.
|
||||
(arc_conditional_register_usage): Allow 64 bit datum into even-odd
|
||||
register pair only. Allow access for ARCv2 accumulator.
|
||||
(gen_compare_reg): Whenever we have FPU support use FPU compare
|
||||
instructions.
|
||||
(arc_reorg): Don't generate brcc insns when FPU compare
|
||||
instructions are involved.
|
||||
* config/arc/arc.h (TARGET_DPFP): Add TARGET_FP_DPAX condition.
|
||||
(TARGET_OPTFPE): Add condition when ARC EM can use optimized
|
||||
floating point emulation.
|
||||
(ACC_REG_FIRST, ACC_REG_LAST, ACCL_REGNO, ACCH_REGNO): Define.
|
||||
(REVERSE_CONDITION): Add new CC_FPU* modes.
|
||||
(TARGET_FP_SP_BASE): Define.
|
||||
(TARGET_FP_DP_BASE): Likewise.
|
||||
(TARGET_FP_SP_FUSED): Likewise.
|
||||
(TARGET_FP_DP_FUSED): Likewise.
|
||||
(TARGET_FP_SP_CONV): Likewise.
|
||||
(TARGET_FP_DP_CONV): Likewise.
|
||||
(TARGET_FP_SP_SQRT): Likewise.
|
||||
(TARGET_FP_DP_SQRT): Likewise.
|
||||
(TARGET_FP_DP_AX): Likewise.
|
||||
* config/arc/arc.md (ARCV2_ACC): New constant.
|
||||
(type): New fpu type attribute.
|
||||
(SDF): Conditional iterator.
|
||||
(cstore<mode>, cbranch<mode>): Change expand condition.
|
||||
(addsf3, subsf3, mulsf3, adddf3, subdf3, muldf3): New expands,
|
||||
handles FPU/FPX cases as well.
|
||||
* config/arc/arc.opt (mfpu): New option.
|
||||
* config/arc/fpx.md (addsf3_fpx, subsf3_fpx, mulsf3_fpx):
|
||||
Renamed.
|
||||
(adddf3, muldf3, subdf3): Removed.
|
||||
* config/arc/predicates.md (proper_comparison_operator): Recognize
|
||||
CC_FPU* modes.
|
||||
* config/arc/fpu.md: New file.
|
||||
* doc/invoke.texi (ARC Options): Document mfpu option.
|
||||
|
||||
2016-02-16 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR rtl-optimization/69291
|
||||
|
@ -35,3 +35,7 @@ CC_MODE (CC_FPX);
|
||||
VECTOR_MODES (INT, 4); /* V4QI V2HI */
|
||||
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
|
||||
VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
|
||||
|
||||
/* FPU condition flags. */
|
||||
CC_MODE (CC_FPU);
|
||||
CC_MODE (CC_FPU_UNEQ);
|
||||
|
@ -27,3 +27,23 @@ enum processor_type
|
||||
PROCESSOR_ARCEM,
|
||||
PROCESSOR_ARCHS
|
||||
};
|
||||
|
||||
/* Single precision floating point. */
|
||||
#define FPU_SP 0x0001
|
||||
/* Single precision fused floating point operations. */
|
||||
#define FPU_SF 0x0002
|
||||
/* Single precision floating point format conversion operations. */
|
||||
#define FPU_SC 0x0004
|
||||
/* Single precision floating point sqrt and div operations. */
|
||||
#define FPU_SD 0x0008
|
||||
/* Double precision floating point. */
|
||||
#define FPU_DP 0x0010
|
||||
/* Double precision fused floating point operations. */
|
||||
#define FPU_DF 0x0020
|
||||
/* Double precision floating point format conversion operations. */
|
||||
#define FPU_DC 0x0040
|
||||
/* Double precision floating point sqrt and div operations. */
|
||||
#define FPU_DD 0x0080
|
||||
/* Double precision floating point assist operations. */
|
||||
#define FPX_DP 0x0100
|
||||
|
||||
|
@ -719,9 +719,16 @@ arc_init (void)
|
||||
|
||||
/* FPX-3. No FPX extensions on pre-ARC600 cores. */
|
||||
if ((TARGET_DPFP || TARGET_SPFP)
|
||||
&& !TARGET_ARCOMPACT_FAMILY)
|
||||
&& (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM))
|
||||
error ("FPX extensions not available on pre-ARC600 cores");
|
||||
|
||||
/* FPX-4. No FPX extensions mixed with FPU extensions for ARC HS
|
||||
cpus. */
|
||||
if ((TARGET_DPFP || TARGET_SPFP)
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& TARGET_HS)
|
||||
error ("No FPX/FPU mixing allowed");
|
||||
|
||||
/* Only selected multiplier configurations are available for HS. */
|
||||
if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7)
|
||||
|| (arc_mpy_option == 1)))
|
||||
@ -743,6 +750,19 @@ arc_init (void)
|
||||
if (TARGET_LL64 && !TARGET_HS)
|
||||
error ("-mll64 is only supported for ARC HS cores");
|
||||
|
||||
/* FPU support only for V2. */
|
||||
if (TARGET_HARD_FLOAT)
|
||||
{
|
||||
if (TARGET_EM
|
||||
&& (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP)))
|
||||
error ("FPU double precision options are available for ARC HS only");
|
||||
if (TARGET_HS && (arc_fpu_build & FPX_DP))
|
||||
error ("FPU double precision assist "
|
||||
"options are not available for ARC HS");
|
||||
if (!TARGET_HS && !TARGET_EM)
|
||||
error ("FPU options are available for ARCv2 architecture only");
|
||||
}
|
||||
|
||||
arc_init_reg_tables ();
|
||||
|
||||
/* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
|
||||
@ -926,6 +946,33 @@ get_arc_condition_code (rtx comparison)
|
||||
case UNEQ : return ARC_CC_LS;
|
||||
default : gcc_unreachable ();
|
||||
}
|
||||
case CC_FPUmode:
|
||||
switch (GET_CODE (comparison))
|
||||
{
|
||||
case EQ : return ARC_CC_EQ;
|
||||
case NE : return ARC_CC_NE;
|
||||
case GT : return ARC_CC_GT;
|
||||
case GE : return ARC_CC_GE;
|
||||
case LT : return ARC_CC_C;
|
||||
case LE : return ARC_CC_LS;
|
||||
case UNORDERED : return ARC_CC_V;
|
||||
case ORDERED : return ARC_CC_NV;
|
||||
case UNGT : return ARC_CC_HI;
|
||||
case UNGE : return ARC_CC_HS;
|
||||
case UNLT : return ARC_CC_LT;
|
||||
case UNLE : return ARC_CC_LE;
|
||||
/* UNEQ and LTGT do not have representation. */
|
||||
case LTGT : /* Fall through. */
|
||||
case UNEQ : /* Fall through. */
|
||||
default : gcc_unreachable ();
|
||||
}
|
||||
case CC_FPU_UNEQmode:
|
||||
switch (GET_CODE (comparison))
|
||||
{
|
||||
case LTGT : return ARC_CC_NE;
|
||||
case UNEQ : return ARC_CC_EQ;
|
||||
default : gcc_unreachable ();
|
||||
}
|
||||
default : gcc_unreachable ();
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
@ -1009,19 +1056,46 @@ arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
|
||||
return CC_FP_GEmode;
|
||||
default: gcc_unreachable ();
|
||||
}
|
||||
else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
|
||||
else if (TARGET_HARD_FLOAT
|
||||
&& ((mode == SFmode && TARGET_FP_SP_BASE)
|
||||
|| (mode == DFmode && TARGET_FP_DP_BASE)))
|
||||
switch (op)
|
||||
{
|
||||
case EQ: case NE: return CC_Zmode;
|
||||
case LT: case UNGE:
|
||||
case GT: case UNLE: return CC_FP_GTmode;
|
||||
case LE: case UNGT:
|
||||
case GE: case UNLT: return CC_FP_GEmode;
|
||||
case UNEQ: case LTGT: return CC_FP_UNEQmode;
|
||||
case ORDERED: case UNORDERED: return CC_FP_ORDmode;
|
||||
default: gcc_unreachable ();
|
||||
}
|
||||
case EQ:
|
||||
case NE:
|
||||
case UNORDERED:
|
||||
case ORDERED:
|
||||
case UNLT:
|
||||
case UNLE:
|
||||
case UNGT:
|
||||
case UNGE:
|
||||
case LT:
|
||||
case LE:
|
||||
case GT:
|
||||
case GE:
|
||||
return CC_FPUmode;
|
||||
|
||||
case LTGT:
|
||||
case UNEQ:
|
||||
return CC_FPU_UNEQmode;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case EQ: case NE: return CC_Zmode;
|
||||
case LT: case UNGE:
|
||||
case GT: case UNLE: return CC_FP_GTmode;
|
||||
case LE: case UNGT:
|
||||
case GE: case UNLT: return CC_FP_GEmode;
|
||||
case UNEQ: case LTGT: return CC_FP_UNEQmode;
|
||||
case ORDERED: case UNORDERED: return CC_FP_ORDmode;
|
||||
default: gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
return CCmode;
|
||||
}
|
||||
|
||||
@ -1148,7 +1222,8 @@ arc_init_reg_tables (void)
|
||||
we must explicitly check for them here. */
|
||||
if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
|
||||
|| i == (int) CC_Cmode
|
||||
|| i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode)
|
||||
|| i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode
|
||||
|| i == CC_FPUmode || i == CC_FPU_UNEQmode)
|
||||
arc_mode_class[i] = 1 << (int) C_MODE;
|
||||
else
|
||||
arc_mode_class[i] = 0;
|
||||
@ -1282,6 +1357,16 @@ arc_conditional_register_usage (void)
|
||||
arc_hard_regno_mode_ok[60] = 1 << (int) S_MODE;
|
||||
}
|
||||
|
||||
/* ARCHS has 64-bit data-path which makes use of the even-odd paired
|
||||
registers. */
|
||||
if (TARGET_HS)
|
||||
{
|
||||
for (regno = 1; regno < 32; regno +=2)
|
||||
{
|
||||
arc_hard_regno_mode_ok[regno] = S_MODES;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
{
|
||||
if (i < 29)
|
||||
@ -1376,6 +1461,19 @@ arc_conditional_register_usage (void)
|
||||
|
||||
/* pc : r63 */
|
||||
arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS;
|
||||
|
||||
/*ARCV2 Accumulator. */
|
||||
if (TARGET_V2
|
||||
&& (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
|
||||
{
|
||||
arc_regno_reg_class[ACCL_REGNO] = WRITABLE_CORE_REGS;
|
||||
arc_regno_reg_class[ACCH_REGNO] = WRITABLE_CORE_REGS;
|
||||
SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCL_REGNO);
|
||||
SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCH_REGNO);
|
||||
SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCL_REGNO);
|
||||
SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCH_REGNO);
|
||||
arc_hard_regno_mode_ok[ACC_REG_FIRST] = D_MODES;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle an "interrupt" attribute; arguments as in
|
||||
@ -1545,6 +1643,10 @@ gen_compare_reg (rtx comparison, machine_mode omode)
|
||||
gen_rtx_REG (CC_FPXmode, 61),
|
||||
const0_rtx)));
|
||||
}
|
||||
else if (TARGET_HARD_FLOAT
|
||||
&& ((cmode == SFmode && TARGET_FP_SP_BASE)
|
||||
|| (cmode == DFmode && TARGET_FP_DP_BASE)))
|
||||
emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
|
||||
else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE)
|
||||
{
|
||||
rtx op0 = gen_rtx_REG (cmode, 0);
|
||||
@ -1638,10 +1740,11 @@ arc_setup_incoming_varargs (cumulative_args_t args_so_far,
|
||||
/* We must treat `__builtin_va_alist' as an anonymous arg. */
|
||||
|
||||
next_cum = *get_cumulative_args (args_so_far);
|
||||
arc_function_arg_advance (pack_cumulative_args (&next_cum), mode, type, 1);
|
||||
arc_function_arg_advance (pack_cumulative_args (&next_cum),
|
||||
mode, type, true);
|
||||
first_anon_arg = next_cum;
|
||||
|
||||
if (first_anon_arg < MAX_ARC_PARM_REGS)
|
||||
if (FUNCTION_ARG_REGNO_P (first_anon_arg))
|
||||
{
|
||||
/* First anonymous (unnamed) argument is in a reg. */
|
||||
|
||||
@ -4856,8 +4959,6 @@ arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This function is used to control a function argument is passed in a
|
||||
register, and which register.
|
||||
|
||||
@ -4895,8 +4996,10 @@ arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
|
||||
and the rest are pushed. */
|
||||
|
||||
static rtx
|
||||
arc_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
|
||||
arc_function_arg (cumulative_args_t cum_v,
|
||||
machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int arg_num = *cum;
|
||||
@ -4942,8 +5045,10 @@ arc_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
course function_arg_partial_nregs will come into play. */
|
||||
|
||||
static void
|
||||
arc_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
arc_function_arg_advance (cumulative_args_t cum_v,
|
||||
machine_mode mode,
|
||||
const_tree type,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int bytes = (mode == BLKmode
|
||||
@ -6398,6 +6503,11 @@ arc_reorg (void)
|
||||
|
||||
pc_target = SET_SRC (pattern);
|
||||
|
||||
/* Avoid FPU instructions. */
|
||||
if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
|
||||
|| (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
|
||||
continue;
|
||||
|
||||
/* Now go back and search for the set cc insn. */
|
||||
|
||||
label = XEXP (pc_target, 1);
|
||||
@ -6420,7 +6530,7 @@ arc_reorg (void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! link_insn)
|
||||
if (!link_insn)
|
||||
continue;
|
||||
else
|
||||
/* Check if this is a data dependency. */
|
||||
|
@ -255,7 +255,8 @@ along with GCC; see the file COPYING3. If not see
|
||||
#define TARGET_MIXED_CODE (TARGET_MIXED_CODE_SET)
|
||||
|
||||
#define TARGET_SPFP (TARGET_SPFP_FAST_SET || TARGET_SPFP_COMPACT_SET)
|
||||
#define TARGET_DPFP (TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET)
|
||||
#define TARGET_DPFP (TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET \
|
||||
|| TARGET_FP_DP_AX)
|
||||
|
||||
#define SUBTARGET_SWITCHES
|
||||
|
||||
@ -266,11 +267,12 @@ along with GCC; see the file COPYING3. If not see
|
||||
default for A7, and only for pre A7 cores when -mnorm is given. */
|
||||
#define TARGET_NORM (TARGET_ARC700 || TARGET_NORM_SET || TARGET_HS)
|
||||
/* Indicate if an optimized floating point emulation library is available. */
|
||||
#define TARGET_OPTFPE \
|
||||
(TARGET_ARC700 \
|
||||
/* We need a barrel shifter and NORM. */ \
|
||||
|| (TARGET_ARC600 && TARGET_NORM_SET) \
|
||||
|| TARGET_HS)
|
||||
#define TARGET_OPTFPE \
|
||||
(TARGET_ARC700 \
|
||||
/* We need a barrel shifter and NORM. */ \
|
||||
|| (TARGET_ARC600 && TARGET_NORM_SET) \
|
||||
|| TARGET_HS \
|
||||
|| (TARGET_EM && TARGET_NORM_SET && TARGET_BARREL_SHIFTER))
|
||||
|
||||
/* Non-zero means the cpu supports swap instruction. This flag is set by
|
||||
default for A7, and only for pre A7 cores when -mswap is given. */
|
||||
@ -713,6 +715,12 @@ enum reg_class
|
||||
#define ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG 136
|
||||
#define ARC_LAST_SIMD_DMA_CONFIG_REG 143
|
||||
|
||||
/* ARCv2 double-register accumulator. */
|
||||
#define ACC_REG_FIRST 58
|
||||
#define ACC_REG_LAST 59
|
||||
#define ACCL_REGNO (TARGET_BIG_ENDIAN ? ACC_REG_FIRST + 1 : ACC_REG_FIRST)
|
||||
#define ACCH_REGNO (TARGET_BIG_ENDIAN ? ACC_REG_FIRST : ACC_REG_FIRST + 1)
|
||||
|
||||
/* The same information, inverted:
|
||||
Return the class number of the smallest class containing
|
||||
reg number REGNO. This could be a conditional expression
|
||||
@ -864,7 +872,7 @@ arc_return_addr_rtx(COUNT,FRAME)
|
||||
for a call to a function whose data type is FNTYPE.
|
||||
For a library call, FNTYPE is 0. */
|
||||
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED_ARGS) \
|
||||
((CUM) = 0)
|
||||
((CUM) = 0)
|
||||
|
||||
/* The number of registers used for parameter passing. Local to this file. */
|
||||
#define MAX_ARC_PARM_REGS 8
|
||||
@ -1656,12 +1664,13 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
|
||||
&& GET_CODE (PATTERN (X)) != CLOBBER \
|
||||
&& get_attr_is_##NAME (X) == IS_##NAME##_YES) \
|
||||
|
||||
#define REVERSE_CONDITION(CODE,MODE) \
|
||||
(((MODE) == CC_FP_GTmode || (MODE) == CC_FP_GEmode \
|
||||
|| (MODE) == CC_FP_UNEQmode || (MODE) == CC_FP_ORDmode \
|
||||
|| (MODE) == CC_FPXmode) \
|
||||
? reverse_condition_maybe_unordered ((CODE)) \
|
||||
: reverse_condition ((CODE)))
|
||||
#define REVERSE_CONDITION(CODE,MODE) \
|
||||
(((MODE) == CC_FP_GTmode || (MODE) == CC_FP_GEmode \
|
||||
|| (MODE) == CC_FP_UNEQmode || (MODE) == CC_FP_ORDmode \
|
||||
|| (MODE) == CC_FPXmode || (MODE) == CC_FPU_UNEQmode \
|
||||
|| (MODE) == CC_FPUmode) \
|
||||
? reverse_condition_maybe_unordered ((CODE)) \
|
||||
: reverse_condition ((CODE)))
|
||||
|
||||
#define ADJUST_INSN_LENGTH(X, LENGTH) \
|
||||
((LENGTH) \
|
||||
@ -1724,4 +1733,26 @@ enum
|
||||
been written to by an ordinary instruction. */
|
||||
#define TARGET_LP_WR_INTERLOCK (!TARGET_ARC600_FAMILY)
|
||||
|
||||
/* FPU defines. */
|
||||
/* Any FPU support. */
|
||||
#define TARGET_HARD_FLOAT (arc_fpu_build != 0)
|
||||
/* Single precision floating point support. */
|
||||
#define TARGET_FP_SP_BASE ((arc_fpu_build & FPU_SP) != 0)
|
||||
/* Double precision floating point support. */
|
||||
#define TARGET_FP_DP_BASE ((arc_fpu_build & FPU_DP) != 0)
|
||||
/* Single precision floating point support with fused operation. */
|
||||
#define TARGET_FP_SP_FUSED ((arc_fpu_build & FPU_SF) != 0)
|
||||
/* Double precision floating point support with fused operation. */
|
||||
#define TARGET_FP_DP_FUSED ((arc_fpu_build & FPU_DF) != 0)
|
||||
/* Single precision floating point conversion instruction support. */
|
||||
#define TARGET_FP_SP_CONV ((arc_fpu_build & FPU_SC) != 0)
|
||||
/* Double precision floating point conversion instruction support. */
|
||||
#define TARGET_FP_DP_CONV ((arc_fpu_build & FPU_DC) != 0)
|
||||
/* Single precision floating point SQRT/DIV instruction support. */
|
||||
#define TARGET_FP_SP_SQRT ((arc_fpu_build & FPU_SD) != 0)
|
||||
/* Double precision floating point SQRT/DIV instruction support. */
|
||||
#define TARGET_FP_DP_SQRT ((arc_fpu_build & FPU_DD) != 0)
|
||||
/* Double precision floating point assist instruction support. */
|
||||
#define TARGET_FP_DP_AX ((arc_fpu_build & FPX_DP) != 0)
|
||||
|
||||
#endif /* GCC_ARC_H */
|
||||
|
@ -175,6 +175,7 @@
|
||||
(ILINK2_REGNUM 30)
|
||||
(RETURN_ADDR_REGNUM 31)
|
||||
(MUL64_OUT_REG 58)
|
||||
(ARCV2_ACC 58)
|
||||
|
||||
(LP_COUNT 60)
|
||||
(CC_REG 61)
|
||||
@ -201,7 +202,8 @@
|
||||
simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
|
||||
simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
|
||||
simd_valign, simd_valign_with_acc, simd_vcontrol,
|
||||
simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem"
|
||||
simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
|
||||
fpu"
|
||||
(cond [(eq_attr "is_sfunc" "yes")
|
||||
(cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
|
||||
(match_test "flag_pic") (const_string "sfunc")]
|
||||
@ -3364,7 +3366,8 @@
|
||||
|
||||
})
|
||||
|
||||
(define_mode_iterator SDF [SF DF])
|
||||
(define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
|
||||
(DF "TARGET_OPTFPE")])
|
||||
|
||||
(define_expand "cstore<mode>4"
|
||||
[(set (reg:CC CC_REG)
|
||||
@ -3374,7 +3377,7 @@
|
||||
(match_operator:SI 1 "comparison_operator" [(reg CC_REG)
|
||||
(const_int 0)]))]
|
||||
|
||||
"TARGET_OPTFPE"
|
||||
"TARGET_FP_SP_BASE || TARGET_OPTFPE"
|
||||
{
|
||||
gcc_assert (XEXP (operands[1], 0) == operands[2]);
|
||||
gcc_assert (XEXP (operands[1], 1) == operands[3]);
|
||||
@ -5167,12 +5170,12 @@
|
||||
(match_operand:SDF 2 "register_operand" "")))
|
||||
(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 0 "comparison_operator" [(reg CC_REG)
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
(match_operator 0 "comparison_operator" [(reg CC_REG)
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
|
||||
"TARGET_OPTFPE"
|
||||
"TARGET_FP_SP_BASE || TARGET_OPTFPE"
|
||||
{
|
||||
gcc_assert (XEXP (operands[0], 0) == operands[1]);
|
||||
gcc_assert (XEXP (operands[0], 1) == operands[2]);
|
||||
@ -5624,9 +5627,155 @@
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "type" "misc")])
|
||||
|
||||
|
||||
;; FPU/FPX expands
|
||||
|
||||
;;add
|
||||
(define_expand "addsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "")
|
||||
(plus:SF (match_operand:SF 1 "nonmemory_operand" "")
|
||||
(match_operand:SF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_FP_SP_BASE || TARGET_SPFP"
|
||||
"
|
||||
if (!register_operand (operands[1], SFmode)
|
||||
&& !register_operand (operands[2], SFmode))
|
||||
operands[1] = force_reg (SFmode, operands[1]);
|
||||
")
|
||||
|
||||
;;sub
|
||||
(define_expand "subsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "")
|
||||
(minus:SF (match_operand:SF 1 "nonmemory_operand" "")
|
||||
(match_operand:SF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_FP_SP_BASE || TARGET_SPFP"
|
||||
"
|
||||
if (!register_operand (operands[1], SFmode)
|
||||
&& !register_operand (operands[2], SFmode))
|
||||
operands[1] = force_reg (SFmode, operands[1]);
|
||||
")
|
||||
|
||||
;;mul
|
||||
(define_expand "mulsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "")
|
||||
(mult:SF (match_operand:SF 1 "nonmemory_operand" "")
|
||||
(match_operand:SF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_FP_SP_BASE || TARGET_SPFP"
|
||||
"
|
||||
if (!register_operand (operands[1], SFmode)
|
||||
&& !register_operand (operands[2], SFmode))
|
||||
operands[1] = force_reg (SFmode, operands[1]);
|
||||
")
|
||||
|
||||
;;add
|
||||
(define_expand "adddf3"
|
||||
[(set (match_operand:DF 0 "double_register_operand" "")
|
||||
(plus:DF (match_operand:DF 1 "double_register_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_FP_DP_BASE || TARGET_DPFP"
|
||||
"
|
||||
if (TARGET_DPFP)
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
split_double (operands[2], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn (gen_adddf3_insn (operands[0], operands[1],
|
||||
operands[2], tmp, const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_adddf3_insn (operands[0], operands[1],
|
||||
operands[2], const1_rtx, const1_rtx));
|
||||
DONE;
|
||||
}
|
||||
else if (TARGET_FP_DP_BASE)
|
||||
{
|
||||
if (!even_register_operand (operands[2], DFmode))
|
||||
operands[2] = force_reg (DFmode, operands[2]);
|
||||
|
||||
if (!even_register_operand (operands[1], DFmode))
|
||||
operands[1] = force_reg (DFmode, operands[1]);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
")
|
||||
|
||||
;;sub
|
||||
(define_expand "subdf3"
|
||||
[(set (match_operand:DF 0 "double_register_operand" "")
|
||||
(minus:DF (match_operand:DF 1 "nonmemory_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_FP_DP_BASE || TARGET_DPFP"
|
||||
"
|
||||
if (TARGET_DPFP)
|
||||
{
|
||||
if ((GET_CODE (operands[1]) == CONST_DOUBLE)
|
||||
|| GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
|
||||
split_double (operands[const_index], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn (gen_subdf3_insn (operands[0], operands[1],
|
||||
operands[2], tmp, const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_subdf3_insn (operands[0], operands[1],
|
||||
operands[2], const1_rtx, const1_rtx));
|
||||
DONE;
|
||||
}
|
||||
else if (TARGET_FP_DP_BASE)
|
||||
{
|
||||
if (!even_register_operand (operands[2], DFmode))
|
||||
operands[2] = force_reg (DFmode, operands[2]);
|
||||
|
||||
if (!even_register_operand (operands[1], DFmode))
|
||||
operands[1] = force_reg (DFmode, operands[1]);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
")
|
||||
|
||||
;;mul
|
||||
(define_expand "muldf3"
|
||||
[(set (match_operand:DF 0 "double_register_operand" "")
|
||||
(mult:DF (match_operand:DF 1 "double_register_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_FP_DP_BASE || TARGET_DPFP"
|
||||
"
|
||||
if (TARGET_DPFP)
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
split_double (operands[2], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn (gen_muldf3_insn (operands[0], operands[1],
|
||||
operands[2], tmp, const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_muldf3_insn (operands[0], operands[1],
|
||||
operands[2], const1_rtx, const1_rtx));
|
||||
DONE;
|
||||
}
|
||||
else if (TARGET_FP_DP_BASE)
|
||||
{
|
||||
if (!even_register_operand (operands[2], DFmode))
|
||||
operands[2] = force_reg (DFmode, operands[2]);
|
||||
|
||||
if (!even_register_operand (operands[1], DFmode))
|
||||
operands[1] = force_reg (DFmode, operands[1]);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
")
|
||||
|
||||
;; include the arc-FPX instructions
|
||||
(include "fpx.md")
|
||||
|
||||
;; include the arc-FPU instructions
|
||||
(include "fpu.md")
|
||||
|
||||
(include "simdext.md")
|
||||
|
||||
;; include atomic extensions
|
||||
|
@ -413,3 +413,46 @@ Enable atomic instructions.
|
||||
mll64
|
||||
Target Report Mask(LL64)
|
||||
Enable double load/store instructions for ARC HS.
|
||||
|
||||
mfpu=
|
||||
Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(0)
|
||||
Specify the name of the target floating point configuration.
|
||||
|
||||
Enum
|
||||
Name(arc_fpu) Type(int)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpus) Value(FPU_SP | FPU_SC)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpud) Value(FPU_SP | FPU_SC | FPU_DP | FPU_DC)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpuda) Value(FPU_SP | FPU_SC | FPX_DP)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpuda_div) Value(FPU_SP | FPU_SC | FPU_SD | FPX_DP)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpuda_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPX_DP)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpuda_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpus_div) Value(FPU_SP | FPU_SC | FPU_SD)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpud_div) Value(FPU_SP | FPU_SC | FPU_SD | FPU_DP | FPU_DC | FPU_DD)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpus_fma) Value(FPU_SP | FPU_SC | FPU_SF)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpud_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPU_DP | FPU_DC | FPU_DF)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
|
||||
|
||||
EnumValue
|
||||
Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
|
||||
|
566
gcc/config/arc/fpu.md
Normal file
566
gcc/config/arc/fpu.md
Normal file
@ -0,0 +1,566 @@
|
||||
;; ::::::::::::::::::::
|
||||
;; ::
|
||||
;; :: 32-bit floating point arithmetic
|
||||
;; ::
|
||||
;; ::::::::::::::::::::
|
||||
|
||||
;; Addition
|
||||
(define_insn "*addsf3_fpu"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r")
|
||||
(plus:SF (match_operand:SF 1 "nonmemory_operand" "%0,r,0,r,F")
|
||||
(match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))]
|
||||
"TARGET_FP_SP_BASE
|
||||
&& (register_operand (operands[1], SFmode)
|
||||
|| register_operand (operands[2], SFmode))"
|
||||
"fsadd%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4,8,8,8")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no,yes,no,no")
|
||||
(set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond")
|
||||
])
|
||||
|
||||
;; Subtraction
|
||||
(define_insn "*subsf3_fpu"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r")
|
||||
(minus:SF (match_operand:SF 1 "nonmemory_operand" "0,r,0,r,F")
|
||||
(match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))]
|
||||
"TARGET_FP_SP_BASE
|
||||
&& (register_operand (operands[1], SFmode)
|
||||
|| register_operand (operands[2], SFmode))"
|
||||
"fssub%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4,8,8,8")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no,yes,no,no")
|
||||
(set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond")
|
||||
])
|
||||
|
||||
;; Multiplication
|
||||
(define_insn "*mulsf3_fpu"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r")
|
||||
(mult:SF (match_operand:SF 1 "nonmemory_operand" "%0,r,0,r,F")
|
||||
(match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))]
|
||||
"TARGET_FP_SP_BASE
|
||||
&& (register_operand (operands[1], SFmode)
|
||||
|| register_operand (operands[2], SFmode))"
|
||||
"fsmul%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4,8,8,8")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no,yes,no,no")
|
||||
(set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond")
|
||||
])
|
||||
|
||||
;; Multiplication with addition/subtraction
|
||||
(define_expand "fmasf4"
|
||||
[(set (match_operand:SF 0 "register_operand" "")
|
||||
(fma:SF (match_operand:SF 1 "nonmemory_operand" "")
|
||||
(match_operand:SF 2 "nonmemory_operand" "")
|
||||
(match_operand:SF 3 "nonmemory_operand" "")))]
|
||||
"TARGET_FP_SP_FUSED"
|
||||
"{
|
||||
rtx tmp;
|
||||
tmp = gen_rtx_REG (SFmode, ACCL_REGNO);
|
||||
emit_move_insn (tmp, operands[3]);
|
||||
operands[3] = tmp;
|
||||
}")
|
||||
|
||||
(define_expand "fnmasf4"
|
||||
[(set (match_operand:SF 0 "register_operand" "")
|
||||
(fma:SF (neg:SF (match_operand:SF 1 "nonmemory_operand" ""))
|
||||
(match_operand:SF 2 "nonmemory_operand" "")
|
||||
(match_operand:SF 3 "nonmemory_operand" "")))]
|
||||
"TARGET_FP_SP_FUSED"
|
||||
"{
|
||||
rtx tmp;
|
||||
tmp = gen_rtx_REG (SFmode, ACCL_REGNO);
|
||||
emit_move_insn (tmp, operands[3]);
|
||||
operands[3] = tmp;
|
||||
}")
|
||||
|
||||
(define_insn "fmasf4_fpu"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r")
|
||||
(fma:SF (match_operand:SF 1 "nonmemory_operand" "%0,r,0,r,F")
|
||||
(match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")
|
||||
(match_operand:SF 3 "mlo_operand" "")))]
|
||||
"TARGET_FP_SP_FUSED
|
||||
&& (register_operand (operands[1], SFmode)
|
||||
|| register_operand (operands[2], SFmode))"
|
||||
"fsmadd%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4,8,8,8")
|
||||
(set_attr "predicable" "yes,no,yes,no,no")
|
||||
(set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")])
|
||||
|
||||
(define_insn "fnmasf4_fpu"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r")
|
||||
(fma:SF (neg:SF (match_operand:SF 1 "nonmemory_operand" "%0,r,0,r,F"))
|
||||
(match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")
|
||||
(match_operand:SF 3 "mlo_operand" "")))]
|
||||
"TARGET_FP_SP_FUSED
|
||||
&& (register_operand (operands[1], SFmode)
|
||||
|| register_operand (operands[2], SFmode))"
|
||||
"fsmsub%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4,8,8,8")
|
||||
(set_attr "predicable" "yes,no,yes,no,no")
|
||||
(set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")])
|
||||
|
||||
(define_expand "fmadf4"
|
||||
[(match_operand:DF 0 "even_register_operand" "")
|
||||
(match_operand:DF 1 "even_register_operand" "")
|
||||
(match_operand:DF 2 "even_register_operand" "")
|
||||
(match_operand:DF 3 "even_register_operand" "")]
|
||||
"TARGET_FP_DP_FUSED"
|
||||
"{
|
||||
emit_insn (gen_fmadf4_split (operands[0], operands[1], operands[2], operands[3]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn_and_split "fmadf4_split"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "")
|
||||
(fma:DF (match_operand:DF 1 "even_register_operand" "")
|
||||
(match_operand:DF 2 "even_register_operand" "")
|
||||
(match_operand:DF 3 "even_register_operand" "")))
|
||||
(clobber (reg:DF ARCV2_ACC))]
|
||||
"TARGET_FP_DP_FUSED"
|
||||
"#"
|
||||
"TARGET_FP_DP_FUSED"
|
||||
[(const_int 0)]
|
||||
"{
|
||||
rtx acc_reg = gen_rtx_REG (DFmode, ACC_REG_FIRST);
|
||||
emit_move_insn (acc_reg, operands[3]);
|
||||
emit_insn (gen_fmadf4_fpu (operands[0], operands[1], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
)
|
||||
|
||||
(define_expand "fnmadf4"
|
||||
[(match_operand:DF 0 "even_register_operand" "")
|
||||
(match_operand:DF 1 "even_register_operand" "")
|
||||
(match_operand:DF 2 "even_register_operand" "")
|
||||
(match_operand:DF 3 "even_register_operand" "")]
|
||||
"TARGET_FP_DP_FUSED"
|
||||
"{
|
||||
emit_insn (gen_fnmadf4_split (operands[0], operands[1], operands[2], operands[3]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn_and_split "fnmadf4_split"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "")
|
||||
(fma:DF (neg:DF (match_operand:DF 1 "even_register_operand" ""))
|
||||
(match_operand:DF 2 "even_register_operand" "")
|
||||
(match_operand:DF 3 "even_register_operand" "")))
|
||||
(clobber (reg:DF ARCV2_ACC))]
|
||||
"TARGET_FP_DP_FUSED"
|
||||
"#"
|
||||
"TARGET_FP_DP_FUSED"
|
||||
[(const_int 0)]
|
||||
"{
|
||||
rtx acc_reg = gen_rtx_REG (DFmode, ACC_REG_FIRST);
|
||||
emit_move_insn (acc_reg, operands[3]);
|
||||
emit_insn (gen_fnmadf4_fpu (operands[0], operands[1], operands[2]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "fmadf4_fpu"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(fma:DF (match_operand:DF 1 "even_register_operand" "%0,r")
|
||||
(match_operand:DF 2 "even_register_operand" "r,r")
|
||||
(reg:DF ARCV2_ACC)))]
|
||||
"TARGET_FP_DP_FUSED"
|
||||
"fdmadd%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "predicable" "yes,no")
|
||||
(set_attr "cond" "canuse,nocond")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")])
|
||||
|
||||
(define_insn "fnmadf4_fpu"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(fma:DF (neg:DF (match_operand:DF 1 "even_register_operand" "%0,r"))
|
||||
(match_operand:DF 2 "even_register_operand" "r,r")
|
||||
(reg:DF ARCV2_ACC)))]
|
||||
"TARGET_FP_DP_FUSED"
|
||||
"fdmsub%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "predicable" "yes,no")
|
||||
(set_attr "cond" "canuse,nocond")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")])
|
||||
|
||||
;; Division
|
||||
(define_insn "divsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r")
|
||||
(div:SF (match_operand:SF 1 "nonmemory_operand" "0,r,0,r,F")
|
||||
(match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))]
|
||||
"TARGET_FP_SP_SQRT"
|
||||
"fsdiv%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4,8,8,8")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no,yes,no,no")
|
||||
(set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond")
|
||||
])
|
||||
|
||||
;; Negation
|
||||
;; see pattern in arc.md
|
||||
|
||||
;; Absolute value
|
||||
;; see pattern in arc.md
|
||||
|
||||
;; Square root
|
||||
(define_insn "sqrtsf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r")
|
||||
(sqrt:SF (match_operand:SF 1 "nonmemory_operand" "r,F")))]
|
||||
"TARGET_FP_SP_SQRT"
|
||||
"fssqrt %0,%1"
|
||||
[(set_attr "length" "4,8")
|
||||
(set_attr "type" "fpu")])
|
||||
|
||||
;; Comparison
|
||||
(define_insn "*cmpsf_fpu"
|
||||
[(set (reg:CC_FPU CC_REG)
|
||||
(compare:CC_FPU (match_operand:SF 0 "register_operand" "r,r")
|
||||
(match_operand:SF 1 "nonmemory_operand" "r,F")))]
|
||||
"TARGET_FP_SP_BASE"
|
||||
"fscmp%? %0, %1"
|
||||
[(set_attr "length" "4,8")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "cond" "set")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,yes")])
|
||||
|
||||
(define_insn "*cmpsf_fpu_uneq"
|
||||
[(set (reg:CC_FPU_UNEQ CC_REG)
|
||||
(compare:CC_FPU_UNEQ
|
||||
(match_operand:SF 0 "register_operand" "r,r")
|
||||
(match_operand:SF 1 "nonmemory_operand" "r,F")))]
|
||||
"TARGET_FP_SP_BASE"
|
||||
"fscmp %0, %1\\n\\tmov.v.f 0,0\\t;set Z flag"
|
||||
[(set_attr "length" "8,12")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "cond" "set")
|
||||
(set_attr "type" "fpu")])
|
||||
|
||||
;; ::::::::::::::::::::
|
||||
;; ::
|
||||
;; :: 64-bit floating point arithmetic
|
||||
;; ::
|
||||
;; ::::::::::::::::::::
|
||||
|
||||
;; Addition
|
||||
(define_insn "*adddf3_fpu"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(plus:DF (match_operand:DF 1 "even_register_operand" "%0,r")
|
||||
(match_operand:DF 2 "even_register_operand" "r,r")))]
|
||||
"TARGET_FP_DP_BASE"
|
||||
"fdadd%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")
|
||||
(set_attr "cond" "canuse,nocond")
|
||||
])
|
||||
|
||||
|
||||
;; Subtraction
|
||||
(define_insn "*subdf3_fpu"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(minus:DF (match_operand:DF 1 "even_register_operand" "0,r")
|
||||
(match_operand:DF 2 "even_register_operand" "r,r")))]
|
||||
"TARGET_FP_DP_BASE"
|
||||
"fdsub%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")
|
||||
(set_attr "cond" "canuse,nocond")
|
||||
])
|
||||
|
||||
;; Multiplication
|
||||
(define_insn "*muldf3_fpu"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(mult:DF (match_operand:DF 1 "even_register_operand" "%0,r")
|
||||
(match_operand:DF 2 "even_register_operand" "r,r")))]
|
||||
"TARGET_FP_DP_BASE"
|
||||
"fdmul%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")
|
||||
(set_attr "cond" "canuse,nocond")
|
||||
])
|
||||
|
||||
;; Division
|
||||
(define_insn "divdf3"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(div:DF (match_operand:DF 1 "even_register_operand" "0,r")
|
||||
(match_operand:DF 2 "even_register_operand" "r,r")))]
|
||||
"TARGET_FP_DP_SQRT"
|
||||
"fddiv%? %0,%1,%2"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")
|
||||
(set_attr "cond" "canuse,nocond")
|
||||
])
|
||||
|
||||
;; Square root
|
||||
(define_insn "sqrtdf2"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r")
|
||||
(sqrt:DF (match_operand:DF 1 "even_register_operand" "r")))]
|
||||
"TARGET_FP_DP_SQRT"
|
||||
"fdsqrt %0,%1"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "type" "fpu")])
|
||||
|
||||
;; Comparison
|
||||
(define_insn "*cmpdf_fpu"
|
||||
[(set (reg:CC_FPU CC_REG)
|
||||
(compare:CC_FPU (match_operand:DF 0 "even_register_operand" "r")
|
||||
(match_operand:DF 1 "even_register_operand" "r")))]
|
||||
"TARGET_FP_DP_BASE"
|
||||
"fdcmp%? %0, %1"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "cond" "set")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes")])
|
||||
|
||||
(define_insn "*cmpdf_fpu_uneq"
|
||||
[(set (reg:CC_FPU_UNEQ CC_REG)
|
||||
(compare:CC_FPU_UNEQ
|
||||
(match_operand:DF 0 "even_register_operand" "r")
|
||||
(match_operand:DF 1 "even_register_operand" "r")))]
|
||||
"TARGET_FP_DP_BASE"
|
||||
"fdcmp %0, %1\\n\\tmov.v.f 0,0\\t;set Z flag"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "cond" "set")
|
||||
(set_attr "type" "fpu")])
|
||||
|
||||
;; ::::::::::::::::::::
|
||||
;; ::
|
||||
;; :: Conversion routines
|
||||
;; ::
|
||||
;; ::::::::::::::::::::
|
||||
|
||||
;; SF->DF
|
||||
(define_insn "extendsfdf2"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(float_extend:DF (match_operand:SF 1 "register_operand" "0,r")))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt32_64%? %0,%1,0x04\\t;fs2d %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; SI->DF
|
||||
(define_insn "floatsidf2"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(float:DF (match_operand:SI 1 "register_operand" "0,r")))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt32_64%? %0,%1,0x02\\t;fint2d %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; uSI->DF
|
||||
(define_insn "floatunssidf2"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(unsigned_float:DF (match_operand:SI 1 "register_operand" "0,r")))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt32_64%? %0,%1,0x00\\t;fuint2d %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; SF->uDI (using rounding towards zero)
|
||||
(define_insn "fixuns_truncsfdi2"
|
||||
[(set (match_operand:DI 0 "even_register_operand" "=r,r")
|
||||
(unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt32_64%? %0,%1,0x09\\t;fs2ul_rz %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; SF->DI (using rounding towards zero)
|
||||
(define_insn "fix_truncsfdi2"
|
||||
[(set (match_operand:DI 0 "even_register_operand" "=r,r")
|
||||
(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt32_64%? %0,%1,0x0B\\t;fs2l_rz %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; SI->SF
|
||||
(define_insn "floatsisf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r")
|
||||
(float:SF (match_operand:SI 1 "register_operand" "0,r")))]
|
||||
"TARGET_FP_SP_CONV"
|
||||
"fcvt32%? %0,%1,0x02\\t;fint2s %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; uSI->SF
|
||||
(define_insn "floatunssisf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r")
|
||||
(unsigned_float:SF (match_operand:SI 1 "register_operand" "0,r")))]
|
||||
"TARGET_FP_SP_CONV"
|
||||
"fcvt32%? %0,%1,0x00\\t;fuint2s %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; SF->uSI (using rounding towards zero)
|
||||
(define_insn "fixuns_truncsfsi2"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))]
|
||||
"TARGET_FP_SP_CONV"
|
||||
"fcvt32%? %0,%1,0x09\\t;fs2uint_rz %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; SF->SI (using rounding towards zero)
|
||||
(define_insn "fix_truncsfsi2"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))]
|
||||
"TARGET_FP_SP_CONV"
|
||||
"fcvt32%? %0,%1,0x0B\\t;fs2int_rz %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; DI->DF
|
||||
(define_insn "floatdidf2"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(float:DF (match_operand:DI 1 "even_register_operand" "0,r")))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64%? %0,%1,0x02\\t;fl2d %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; uDI->DF
|
||||
(define_insn "floatunsdidf2"
|
||||
[(set (match_operand:DF 0 "even_register_operand" "=r,r")
|
||||
(unsigned_float:DF (match_operand:DI 1 "even_register_operand" "0,r")))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64%? %0,%1,0x00\\t;ful2d %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; DF->uDI (using rounding towards zero)
|
||||
(define_insn "fixuns_truncdfdi2"
|
||||
[(set (match_operand:DI 0 "even_register_operand" "=r,r")
|
||||
(unsigned_fix:DI (fix:DF (match_operand:DF 1 "even_register_operand" "0,r"))))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64%? %0,%1,0x09\\t;fd2ul_rz %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; DF->DI (using rounding towards zero)
|
||||
(define_insn "fix_truncdfdi2"
|
||||
[(set (match_operand:DI 0 "even_register_operand" "=r,r")
|
||||
(fix:DI (fix:DF (match_operand:DF 1 "even_register_operand" "0,r"))))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64%? %0,%1,0x0B\\t;fd2l_rz %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; DF->SF
|
||||
(define_insn "truncdfsf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r")
|
||||
(float_truncate:SF (match_operand:DF 1 "even_register_operand" "0,r")))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64_32%? %0,%1,0x04\\t;fd2s %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; DI->SF
|
||||
(define_insn "floatdisf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r")
|
||||
(float:SF (match_operand:DI 1 "even_register_operand" "0,r")))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64_32%? %0,%1,0x02\\t;fl2s %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; uDI->SF
|
||||
(define_insn "floatunsdisf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r")
|
||||
(unsigned_float:SF (match_operand:DI 1 "even_register_operand" "0,r")))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64_32%? %0,%1,0x00\\t;ful2s %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; DF->uSI (using rounding towards zero)
|
||||
(define_insn "fixuns_truncdfsi2"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
(unsigned_fix:SI (fix:DF (match_operand:DF 1 "even_register_operand" "0,r"))))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64_32%? %0,%1,0x09\\t;fd2uint_rz %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
||||
|
||||
;; DF->SI (using rounding towards zero)
|
||||
(define_insn "fix_truncdfsi2"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
(fix:SI (fix:DF (match_operand:DF 1 "even_register_operand" "0,r"))))]
|
||||
"TARGET_FP_DP_CONV"
|
||||
"fcvt64_32%? %0,%1,0x0B\\t;fd2int_rz %0,%1"
|
||||
[(set_attr "length" "4,4")
|
||||
(set_attr "iscompact" "false")
|
||||
(set_attr "type" "fpu")
|
||||
(set_attr "predicable" "yes,no")]
|
||||
)
|
@ -50,7 +50,7 @@
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define_insn "addsf3"
|
||||
(define_insn "*addsf3_fpx"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
|
||||
(plus:SF (match_operand:SF 1 "nonmemory_operand" "0,r,GCal,r,0")
|
||||
(match_operand:SF 2 "nonmemory_operand" "I,rL,r,GCal,LrCal")))]
|
||||
@ -65,7 +65,7 @@
|
||||
[(set_attr "type" "spfp")
|
||||
(set_attr "length" "4,4,8,8,8")])
|
||||
|
||||
(define_insn "subsf3"
|
||||
(define_insn "*subsf3_fpx"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
|
||||
(minus:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0")
|
||||
(match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))]
|
||||
@ -80,7 +80,7 @@
|
||||
[(set_attr "type" "spfp")
|
||||
(set_attr "length" "4,4,8,8,8")])
|
||||
|
||||
(define_insn "mulsf3"
|
||||
(define_insn "*mulsf3_fpx"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
|
||||
(mult:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0")
|
||||
(match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))]
|
||||
@ -226,25 +226,6 @@
|
||||
;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
|
||||
;; OR
|
||||
;; daddh{0}{1} 0, reg3, limm2.lo
|
||||
(define_expand "adddf3"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "")
|
||||
(plus:DF (match_operand:DF 1 "arc_double_register_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))
|
||||
]
|
||||
"TARGET_DPFP"
|
||||
" if (GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
split_double (operands[2], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn(gen_adddf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn(gen_adddf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
|
||||
DONE;
|
||||
"
|
||||
)
|
||||
|
||||
;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
|
||||
;; OR
|
||||
;; daddh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0 */
|
||||
@ -270,25 +251,6 @@
|
||||
;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
|
||||
;; OR
|
||||
;; dmulh{0}{1} 0, reg3, limm2.lo
|
||||
(define_expand "muldf3"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "")
|
||||
(mult:DF (match_operand:DF 1 "arc_double_register_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_DPFP"
|
||||
" if (GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
split_double (operands[2], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn(gen_muldf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn(gen_muldf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
|
||||
|
||||
DONE;
|
||||
")
|
||||
|
||||
|
||||
;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
|
||||
;; OR
|
||||
;; dmulh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
|
||||
@ -317,26 +279,6 @@
|
||||
;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo
|
||||
;; OR
|
||||
;; drsubh{0}{2} 0, reg3, limm1.lo
|
||||
(define_expand "subdf3"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "")
|
||||
(minus:DF (match_operand:DF 1 "nonmemory_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_DPFP"
|
||||
" if (GET_CODE (operands[1]) == CONST_DOUBLE || GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1: 2);
|
||||
split_double (operands[const_index], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn(gen_subdf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn(gen_subdf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
|
||||
|
||||
DONE;
|
||||
"
|
||||
)
|
||||
|
||||
;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1 */
|
||||
;; OR
|
||||
;; dsubh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
|
||||
|
@ -504,6 +504,11 @@
|
||||
return (code == EQ || code == NE || code == UNEQ || code == LTGT
|
||||
|| code == ORDERED || code == UNORDERED);
|
||||
|
||||
case CC_FPUmode:
|
||||
return 1;
|
||||
case CC_FPU_UNEQmode:
|
||||
return 1;
|
||||
|
||||
case CCmode:
|
||||
case SImode: /* Used for BRcc. */
|
||||
return 1;
|
||||
@ -797,3 +802,7 @@
|
||||
return (REG_P (op) && ((REGNO (op) >= FIRST_PSEUDO_REGISTER)
|
||||
|| ((REGNO (op) & 1) == 0)));
|
||||
})
|
||||
|
||||
(define_predicate "double_register_operand"
|
||||
(ior (match_test "even_register_operand (op, mode)")
|
||||
(match_test "arc_double_register_operand (op, mode)")))
|
||||
|
@ -599,7 +599,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-mmixed-code -mq-class -mRcq -mRcw -msize-level=@var{level} @gol
|
||||
-mtune=@var{cpu} -mmultcost=@var{num} @gol
|
||||
-munalign-prob-threshold=@var{probability} -mmpy-option=@var{multo} @gol
|
||||
-mdiv-rem -mcode-density -mll64}
|
||||
-mdiv-rem -mcode-density -mll64 -mfpu=@var{fpu}}
|
||||
|
||||
@emph{ARM Options}
|
||||
@gccoptlist{-mapcs-frame -mno-apcs-frame @gol
|
||||
@ -13325,6 +13325,88 @@ MPYU, MPYM, MPYMU, and MPY_S.
|
||||
|
||||
This option is only available for ARCv2 cores@.
|
||||
|
||||
@item -mfpu=@var{fpu}
|
||||
@opindex mfpu
|
||||
Enables specific floating-point hardware extension for ARCv2
|
||||
core. Supported values for @var{fpu} are:
|
||||
|
||||
@table @samp
|
||||
|
||||
@item fpus
|
||||
@opindex fpus
|
||||
Enables support for single precision floating point hardware
|
||||
extensions@.
|
||||
|
||||
@item fpud
|
||||
@opindex fpud
|
||||
Enables support for double precision floating point hardware
|
||||
extensions. The single precision floating point extension is also
|
||||
enabled. Not available for ARC EM@.
|
||||
|
||||
@item fpuda
|
||||
@opindex fpuda
|
||||
Enables support for double precision floating point hardware
|
||||
extensions using double precision assist instructions. The single
|
||||
precision floating point extension is also enabled. This option is
|
||||
only available for ARC EM@.
|
||||
|
||||
@item fpuda_div
|
||||
@opindex fpuda_div
|
||||
Enables support for double precision floating point hardware
|
||||
extensions using double precision assist instructions, and simple
|
||||
precision square-root and divide hardware extensions. The single
|
||||
precision floating point extension is also enabled. This option is
|
||||
only available for ARC EM@.
|
||||
|
||||
@item fpuda_fma
|
||||
@opindex fpuda_fma
|
||||
Enables support for double precision floating point hardware
|
||||
extensions using double precision assist instructions, and simple
|
||||
precision fused multiple and add hardware extension. The single
|
||||
precision floating point extension is also enabled. This option is
|
||||
only available for ARC EM@.
|
||||
|
||||
@item fpuda_all
|
||||
@opindex fpuda_all
|
||||
Enables support for double precision floating point hardware
|
||||
extensions using double precision assist instructions, and all simple
|
||||
precision hardware extensions. The single precision floating point
|
||||
extension is also enabled. This option is only available for ARC EM@.
|
||||
|
||||
@item fpus_div
|
||||
@opindex fpus_div
|
||||
Enables support for single precision floating point, and single
|
||||
precision square-root and divide hardware extensions@.
|
||||
|
||||
@item fpud_div
|
||||
@opindex fpud_div
|
||||
Enables support for double precision floating point, and double
|
||||
precision square-root and divide hardware extensions. This option
|
||||
includes option @samp{fpus_div}. Not available for ARC EM@.
|
||||
|
||||
@item fpus_fma
|
||||
@opindex fpus_fma
|
||||
Enables support for single precision floating point, and single
|
||||
precision fused multiple and add hardware extensions@.
|
||||
|
||||
@item fpud_fma
|
||||
@opindex fpud_fma
|
||||
Enables support for double precision floating point, and double
|
||||
precision fused multiple and add hardware extensions. This option
|
||||
includes option @samp{fpus_fma}. Not available for ARC EM@.
|
||||
|
||||
@item fpus_all
|
||||
@opindex fpus_all
|
||||
Enables support for all single precision floating point hardware
|
||||
extensions@.
|
||||
|
||||
@item fpud_all
|
||||
@opindex fpud_all
|
||||
Enables support for all single and double precision floating point
|
||||
hardware extensions. Not available for ARC EM@.
|
||||
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
The following options are passed through to the assembler, and also
|
||||
|
Loading…
Reference in New Issue
Block a user