+2007-07-21 Uros Bizjak <ubizjak@gmail.com>
+
+ * 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 (signbit<mode>2): New insn pattern to implement
+ signbitf, signbit and signbitl built-ins as inline x87 intrinsics when
+ SSE mode is not active.
+ (isinf<mode>2): Disable for mfpmath=sse,387.
+
2007-07-22 Ben Elliston <bje@au.ibm.com>
* regclass.c (invalid_mode_change_p): Attach ATTRIBUTE_UNUSED to
2007-07-16 Paul Brook <paul@codesourcery.com>
PR target/32753
- gcc/
* config/arm/cirrus.md (cirrus_arm_movsi_insn): Remove dead insn.
(cirrus_thumb2_movsi_insn): Ditto.
offsets->locals_base to avoid negative stack size.
(thumb1_expand_prologue): Assert on negative stack size.
-2007-04-19 Sebastian Pop <sebpop@gmail.com>
+2007-06-19 Sebastian Pop <sebpop@gmail.com>
PR tree-optimization/32367
* tree-chrec.h (build_polynomial_chrec): Verify that the left hand side
float constant.
(_m_to_float): Use C89 compatible assignment.
-2007-04-20 Martin Michlmayr <tbm@cyrius.com>
+2007-05-20 Martin Michlmayr <tbm@cyrius.com>
PR target/32007
* config/arm/lib1funcs.asm: Define __ARM_ARCH__ on v2/v3 machines.
size never inline functions increasing caller size.
(cgraph_early_inlining): Inline for size when optimizing for size.
-2007-04-18 Bernd Schmidt <bernd.schmidt@analog.com>
+2007-05-04 Bernd Schmidt <bernd.schmidt@analog.com>
* config/bfin/bfin.md (<optab>di3): Now a define_expand which expands
logical operations piecewise.
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". */
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))
/* 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;
}
(use (match_operand:X87MODEF 1 "register_operand" ""))]
"TARGET_USE_FANCY_MATH_387
&& TARGET_C99_FUNCTIONS
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)"
+ && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
{
rtx mask = GEN_INT (0x45);
rtx val = GEN_INT (0x05);
DONE;
})
+(define_expand "signbit<mode>2"
+ [(use (match_operand:SI 0 "register_operand" ""))
+ (use (match_operand:X87MODEF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+{
+ rtx mask = GEN_INT (0x0200);
+
+ rtx scratch = gen_reg_rtx (HImode);
+
+ emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
+ emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
+ DONE;
+})
\f
;; Block operation instructions
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);
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);
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;
OTI_atan,
/* Copy sign */
OTI_copysign,
-
+ /* Signbit */
+ OTI_signbit,
/* Test for infinite value */
OTI_isinf,
#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])
/* 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];