From: uros Date: Sat, 21 Jul 2007 21:45:06 +0000 (+0000) Subject: * optabs.h (enum optab_index): Add new OTI_signbit. X-Git-Tag: upstream/4.9.2~47371 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=27eda24040c703c6ecd3eadc44c78eb80098b995;p=platform%2Fupstream%2Flinaro-gcc.git * optabs.h (enum optab_index): Add new OTI_signbit. (signbit_optab): Define corresponding macro. (enum insn_code signbit_optab[]): Remove array. * optabs.c (init_optabs): Initialize signbit_optab using init_optab. (expand_copysign_absneg): If back end provides signbit insn, use it instead of bit operations on floating point argument. * builtins.c (enum insn_code signbit_optab[]): Remove array. (expand_builtin_signbit): Check signbit_optab->handlers[].insn_code for availability of signbit insn. * config/i386/i386.md (signbit2): New insn pattern to implement signbitf, signbit and signbitl built-ins as inline x87 intrinsics when SSE mode is not active. (isinf2): Disable for mfpmath=sse,387. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126813 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 92579ec..5d4982d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2007-07-21 Uros Bizjak + + * optabs.h (enum optab_index): Add new OTI_signbit. + (signbit_optab): Define corresponding macro. + (enum insn_code signbit_optab[]): Remove array. + * optabs.c (init_optabs): Initialize signbit_optab using init_optab. + (expand_copysign_absneg): If back end provides signbit insn, use it + instead of bit operations on floating point argument. + * builtins.c (enum insn_code signbit_optab[]): Remove array. + (expand_builtin_signbit): Check signbit_optab->handlers[].insn_code for + availability of signbit insn. + + * config/i386/i386.md (signbit2): New insn pattern to implement + signbitf, signbit and signbitl built-ins as inline x87 intrinsics when + SSE mode is not active. + (isinf2): Disable for mfpmath=sse,387. + 2007-07-22 Ben Elliston * regclass.c (invalid_mode_change_p): Attach ATTRIBUTE_UNUSED to @@ -256,7 +273,6 @@ 2007-07-16 Paul Brook PR target/32753 - gcc/ * config/arm/cirrus.md (cirrus_arm_movsi_insn): Remove dead insn. (cirrus_thumb2_movsi_insn): Ditto. @@ -2753,7 +2769,7 @@ offsets->locals_base to avoid negative stack size. (thumb1_expand_prologue): Assert on negative stack size. -2007-04-19 Sebastian Pop +2007-06-19 Sebastian Pop PR tree-optimization/32367 * tree-chrec.h (build_polynomial_chrec): Verify that the left hand side @@ -6068,7 +6084,7 @@ float constant. (_m_to_float): Use C89 compatible assignment. -2007-04-20 Martin Michlmayr +2007-05-20 Martin Michlmayr PR target/32007 * config/arm/lib1funcs.asm: Define __ARM_ARCH__ on v2/v3 machines. @@ -7084,7 +7100,7 @@ size never inline functions increasing caller size. (cgraph_early_inlining): Inline for size when optimizing for size. -2007-04-18 Bernd Schmidt +2007-05-04 Bernd Schmidt * config/bfin/bfin.md (di3): Now a define_expand which expands logical operations piecewise. diff --git a/gcc/builtins.c b/gcc/builtins.c index d0e5db9..a2e4be8 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -240,11 +240,6 @@ static tree do_mpfr_remquo (tree, tree, tree); static tree do_mpfr_lgamma_r (tree, tree, tree); #endif -/* This array records the insn_code of insns to imlement the signbit - function. */ -enum insn_code signbit_optab[NUM_MACHINE_MODES]; - - /* Return true if NODE should be considered for inline expansion regardless of the optimization level. This means whenever a function is invoked with its "internal" name, which normally contains the prefix "__builtin". */ @@ -5725,7 +5720,7 @@ expand_builtin_signbit (tree exp, rtx target) HOST_WIDE_INT hi, lo; tree arg; int word, bitpos; - enum insn_code signbit_insn_code; + enum insn_code icode; rtx temp; if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) @@ -5743,11 +5738,11 @@ expand_builtin_signbit (tree exp, rtx target) /* Check if the back end provides an insn that handles signbit for the argument's mode. */ - signbit_insn_code = signbit_optab [(int) fmode]; - if (signbit_insn_code != CODE_FOR_nothing) + icode = signbit_optab->handlers [(int) fmode].insn_code; + if (icode != CODE_FOR_nothing) { target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp))); - emit_unop_insn (signbit_insn_code, target, temp, UNKNOWN); + emit_unop_insn (icode, target, temp, UNKNOWN); return target; } diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index e258447..0377735 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -17990,8 +17990,7 @@ (use (match_operand:X87MODEF 1 "register_operand" ""))] "TARGET_USE_FANCY_MATH_387 && TARGET_C99_FUNCTIONS - && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) - || TARGET_MIX_SSE_I387)" + && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)" { rtx mask = GEN_INT (0x45); rtx val = GEN_INT (0x05); @@ -18012,6 +18011,20 @@ DONE; }) +(define_expand "signbit2" + [(use (match_operand:SI 0 "register_operand" "")) + (use (match_operand:X87MODEF 1 "register_operand" ""))] + "TARGET_USE_FANCY_MATH_387 + && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)" +{ + rtx mask = GEN_INT (0x0200); + + rtx scratch = gen_reg_rtx (HImode); + + emit_insn (gen_fxam2_i387 (scratch, operands[1])); + emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask)); + DONE; +}) ;; Block operation instructions diff --git a/gcc/optabs.c b/gcc/optabs.c index 95b2ec9..c754544 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3112,63 +3112,79 @@ expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target, int bitpos, bool op0_is_abs) { enum machine_mode imode; - HOST_WIDE_INT hi, lo; - int word; - rtx label; + int icode; + rtx sign, label; if (target == op1) target = NULL_RTX; - if (!op0_is_abs) + /* Check if the back end provides an insn that handles signbit for the + argument's mode. */ + icode = (int) signbit_optab->handlers [(int) mode].insn_code; + if (icode != CODE_FOR_nothing) { - op0 = expand_unop (mode, abs_optab, op0, target, 0); - if (op0 == NULL) - return NULL_RTX; - target = op0; + imode = insn_data[icode].operand[0].mode; + sign = gen_reg_rtx (imode); + emit_unop_insn (icode, sign, op1, UNKNOWN); } else { - if (target == NULL_RTX) - target = copy_to_reg (op0); + HOST_WIDE_INT hi, lo; + + if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) + { + imode = int_mode_for_mode (mode); + if (imode == BLKmode) + return NULL_RTX; + op1 = gen_lowpart (imode, op1); + } else - emit_move_insn (target, op0); - } + { + int word; - if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) - { - imode = int_mode_for_mode (mode); - if (imode == BLKmode) - return NULL_RTX; - op1 = gen_lowpart (imode, op1); - } - else - { - imode = word_mode; - if (FLOAT_WORDS_BIG_ENDIAN) - word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD; + imode = word_mode; + if (FLOAT_WORDS_BIG_ENDIAN) + word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD; + else + word = bitpos / BITS_PER_WORD; + bitpos = bitpos % BITS_PER_WORD; + op1 = operand_subword_force (op1, word, mode); + } + + if (bitpos < HOST_BITS_PER_WIDE_INT) + { + hi = 0; + lo = (HOST_WIDE_INT) 1 << bitpos; + } else - word = bitpos / BITS_PER_WORD; - bitpos = bitpos % BITS_PER_WORD; - op1 = operand_subword_force (op1, word, mode); + { + hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); + lo = 0; + } + + sign = gen_reg_rtx (imode); + sign = expand_binop (imode, and_optab, op1, + immed_double_const (lo, hi, imode), + NULL_RTX, 1, OPTAB_LIB_WIDEN); } - if (bitpos < HOST_BITS_PER_WIDE_INT) + if (!op0_is_abs) { - hi = 0; - lo = (HOST_WIDE_INT) 1 << bitpos; + op0 = expand_unop (mode, abs_optab, op0, target, 0); + if (op0 == NULL) + return NULL_RTX; + target = op0; } else { - hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); - lo = 0; + if (target == NULL_RTX) + target = copy_to_reg (op0); + else + emit_move_insn (target, op0); } - op1 = expand_binop (imode, and_optab, op1, - immed_double_const (lo, hi, imode), - NULL_RTX, 1, OPTAB_LIB_WIDEN); - label = gen_label_rtx (); - emit_cmp_and_jump_insns (op1, const0_rtx, EQ, NULL_RTX, imode, 1, label); + emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label); if (GET_CODE (op0) == CONST_DOUBLE) op0 = simplify_unary_operation (NEG, mode, op0, mode); @@ -5585,6 +5601,7 @@ init_optabs (void) tan_optab = init_optab (UNKNOWN); atan_optab = init_optab (UNKNOWN); copysign_optab = init_optab (UNKNOWN); + signbit_optab = init_optab (UNKNOWN); isinf_optab = init_optab (UNKNOWN); @@ -5655,7 +5672,6 @@ init_optabs (void) for (i = 0; i < NUM_MACHINE_MODES; i++) { movmem_optab[i] = CODE_FOR_nothing; - signbit_optab[i] = CODE_FOR_nothing; cmpstr_optab[i] = CODE_FOR_nothing; cmpstrn_optab[i] = CODE_FOR_nothing; cmpmem_optab[i] = CODE_FOR_nothing; diff --git a/gcc/optabs.h b/gcc/optabs.h index aed7a54..d8917ab 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -219,7 +219,8 @@ enum optab_index OTI_atan, /* Copy sign */ OTI_copysign, - + /* Signbit */ + OTI_signbit, /* Test for infinite value */ OTI_isinf, @@ -409,7 +410,7 @@ extern GTY(()) optab optab_table[OTI_MAX]; #define tan_optab (optab_table[OTI_tan]) #define atan_optab (optab_table[OTI_atan]) #define copysign_optab (optab_table[OTI_copysign]) - +#define signbit_optab (optab_table[OTI_signbit]) #define isinf_optab (optab_table[OTI_isinf]) #define cmp_optab (optab_table[OTI_cmp]) @@ -553,9 +554,6 @@ extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES]; /* This array records the insn_code of insns to perform block moves. */ extern enum insn_code movmem_optab[NUM_MACHINE_MODES]; -/* This array records the insn_code of insns to implement the signbit function. */ -extern enum insn_code signbit_optab[NUM_MACHINE_MODES]; - /* This array records the insn_code of insns to perform block sets. */ extern enum insn_code setmem_optab[NUM_MACHINE_MODES];