if (flag_force_mem)
{
- op0 = force_not_mem (op0);
- op1 = force_not_mem (op1);
+ /* Load duplicate non-volatile operands once. */
+ if (rtx_equal_p (op0, op1) && ! volatile_refs_p (op0))
+ {
+ op0 = force_not_mem (op0);
+ op1 = op0;
+ }
+ else
+ {
+ op0 = force_not_mem (op0);
+ op1 = force_not_mem (op1);
+ }
}
/* If subtracting an integer constant, convert this into an addition of
if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
{
- if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
+ if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
+ || ! rtx_equal_p (target, xtarget))
{
rtx temp = emit_move_insn (target, xtarget);
temp1 = expand_binop (submode, binoptab, real0, imag1,
NULL_RTX, unsignedp, methods);
- temp2 = expand_binop (submode, binoptab, real1, imag0,
- NULL_RTX, unsignedp, methods);
+ /* Avoid expanding redundant multiplication for the common
+ case of squaring a complex number. */
+ if (rtx_equal_p (real0, real1) && rtx_equal_p (imag0, imag1))
+ temp2 = temp1;
+ else
+ temp2 = expand_binop (submode, binoptab, real1, imag0,
+ NULL_RTX, unsignedp, methods);
if (temp1 == 0 || temp2 == 0)
break;
*/
rtx
-expand_abs (mode, op0, target, result_unsignedp, safe)
+expand_abs_nojump (mode, op0, target, result_unsignedp)
enum machine_mode mode;
rtx op0;
rtx target;
int result_unsignedp;
- int safe;
{
- rtx temp, op1;
+ rtx temp;
if (! flag_trapv)
result_unsignedp = 1;
return temp;
}
+ return NULL_RTX;
+}
+
+rtx
+expand_abs (mode, op0, target, result_unsignedp, safe)
+ enum machine_mode mode;
+ rtx op0;
+ rtx target;
+ int result_unsignedp;
+ int safe;
+{
+ rtx temp, op1;
+
+ temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
+ if (temp != 0)
+ return temp;
+
/* If that does not win, use conditional jump and negate. */
/* It is safe to use the target if it is the same
if (mode != BLKmode && flag_force_mem)
{
- x = force_not_mem (x);
- y = force_not_mem (y);
+ /* Load duplicate non-volatile operands once. */
+ if (rtx_equal_p (x, y) && ! volatile_refs_p (x))
+ {
+ x = force_not_mem (x);
+ y = x;
+ }
+ else
+ {
+ x = force_not_mem (x);
+ y = force_not_mem (y);
+ }
}
/* If we are inside an appropriately-short loop and one operand is an
init_one_libfunc (name)
const char *name;
{
+ rtx symbol;
+
/* Create a FUNCTION_DECL that can be passed to
targetm.encode_section_info. */
/* ??? We don't have any type information except for this is
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
- /* Return the symbol_ref from the mem rtx. */
- return XEXP (DECL_RTL (decl), 0);
+ symbol = XEXP (DECL_RTL (decl), 0);
+
+ /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
+ are the flags assigned by targetm.encode_section_info. */
+ SYMBOL_REF_DECL (symbol) = 0;
+
+ return symbol;
}
/* Call this once to initialize the contents of the optabs