{
if (reg_overlap_mentioned_p (to, from))
from = force_reg (from_mode, from);
- emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
+ emit_clobber (to);
}
convert_move (word_to, from, unsignedp);
emit_unop_insn (code, to, word_to, equiv_code);
insns = get_insns ();
end_sequence ();
- emit_no_conflict_block (insns, to, from, NULL_RTX,
- gen_rtx_fmt_e (equiv_code, to_mode, copy_rtx (from)));
+ emit_insn (insns);
return;
}
static bool
block_move_libcall_safe_for_call_parm (void)
{
+#if defined (REG_PARM_STACK_SPACE)
+ tree fn;
+#endif
+
/* If arguments are pushed on the stack, then they're safe. */
if (PUSH_ARGS)
return true;
/* If registers go on the stack anyway, any argument is sure to clobber
an outgoing argument. */
#if defined (REG_PARM_STACK_SPACE)
- if (OUTGOING_REG_PARM_STACK_SPACE)
- {
- tree fn;
- fn = emit_block_move_libcall_fn (false);
- if (REG_PARM_STACK_SPACE (fn) != 0)
- return false;
- }
+ fn = emit_block_move_libcall_fn (false);
+ if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn)))
+ && REG_PARM_STACK_SPACE (fn) != 0)
+ return false;
#endif
/* If any argument goes in memory, then it might clobber an outgoing
hard regs shouldn't appear here except as return values. */
if (!reload_completed && !reload_in_progress
&& REG_P (x) && !reg_overlap_mentioned_p (x, y))
- emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
+ emit_clobber (x);
write_complex_part (x, read_complex_part (y, false), false);
write_complex_part (x, read_complex_part (y, true), true);
if (x != y
&& ! (reload_in_progress || reload_completed)
&& need_clobber != 0)
- emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
+ emit_clobber (x);
emit_insn (seq);
the place the value is being stored, use a safe function when copying
a value through a pointer into a structure value return block. */
if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF
- && current_function_returns_struct
- && !current_function_returns_pcc_struct)
+ && cfun->returns_struct
+ && !cfun->returns_pcc_struct)
{
rtx from_rtx, size;
}
if (REG_P (target) && !cleared)
- emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
+ emit_clobber (target);
/* Store each element of the constructor into the
corresponding field of TARGET. */
if (!cleared && REG_P (target))
/* Inform later passes that the old value is dead. */
- emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
+ emit_clobber (target);
/* Store each element of the constructor into the
corresponding element of TARGET, determined by counting the
&& mode != TYPE_MODE (TREE_TYPE (exp)))
temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
- /* If the modes of TARGET and TEMP are both BLKmode, both
+ /* If the modes of TEMP and TARGET are both BLKmode, both
must be in memory and BITPOS must be aligned on a byte
- boundary. If so, we simply do a block copy. */
- if (GET_MODE (target) == BLKmode && GET_MODE (temp) == BLKmode)
+ boundary. If so, we simply do a block copy. Likewise
+ for a BLKmode-like TARGET. */
+ if (GET_MODE (temp) == BLKmode
+ && (GET_MODE (target) == BLKmode
+ || (MEM_P (target)
+ && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT
+ && (bitpos % BITS_PER_UNIT) == 0
+ && (bitsize % BITS_PER_UNIT) == 0)))
{
gcc_assert (MEM_P (target) && MEM_P (temp)
- && !(bitpos % BITS_PER_UNIT));
+ && (bitpos % BITS_PER_UNIT) == 0);
target = adjust_address (target, VOIDmode, bitpos / BITS_PER_UNIT);
emit_block_move (target, temp,
If any of the extraction expressions is volatile,
we store 1 in *PVOLATILEP. Otherwise we don't change that.
- If the field is a bit-field, *PMODE is set to VOIDmode. Otherwise, it
- is a mode that can be used to access the field. In that case, *PBITSIZE
- is redundant.
+ If the field is a non-BLKmode bit-field, *PMODE is set to VOIDmode.
+ Otherwise, it is a mode that can be used to access the field.
If the field describes a variable-sized object, *PMODE is set to
- VOIDmode and *PBITSIZE is set to -1. An access cannot be made in
+ BLKmode and *PBITSIZE is set to -1. An access cannot be made in
this case, but the address of the object can be found.
If KEEP_ALIGNING is true and the target is STRICT_ALIGNMENT, we don't
{
tree size_tree = 0;
enum machine_mode mode = VOIDmode;
+ bool blkmode_bitfield = false;
tree offset = size_zero_node;
tree bit_offset = bitsize_zero_node;
outermost expression. */
if (TREE_CODE (exp) == COMPONENT_REF)
{
- size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
- if (! DECL_BIT_FIELD (TREE_OPERAND (exp, 1)))
- mode = DECL_MODE (TREE_OPERAND (exp, 1));
+ tree field = TREE_OPERAND (exp, 1);
+ size_tree = DECL_SIZE (field);
+ if (!DECL_BIT_FIELD (field))
+ mode = DECL_MODE (field);
+ else if (DECL_MODE (field) == BLKmode)
+ blkmode_bitfield = true;
- *punsignedp = DECL_UNSIGNED (TREE_OPERAND (exp, 1));
+ *punsignedp = DECL_UNSIGNED (field);
}
else if (TREE_CODE (exp) == BIT_FIELD_REF)
{
*pbitsize = tree_low_cst (size_tree, 1);
}
- *pmode = mode;
-
/* Compute cumulative bit-offset for nested component-refs and array-refs,
and find the ultimate containing object. */
while (1)
if (double_int_fits_in_shwi_p (tem))
{
*pbitpos = double_int_to_shwi (tem);
- *poffset = NULL_TREE;
- return exp;
+ *poffset = offset = NULL_TREE;
}
}
/* Otherwise, split it up. */
- *pbitpos = tree_low_cst (bit_offset, 0);
- *poffset = offset;
+ if (offset)
+ {
+ *pbitpos = tree_low_cst (bit_offset, 0);
+ *poffset = offset;
+ }
+
+ /* We can use BLKmode for a byte-aligned BLKmode bitfield. */
+ if (mode == VOIDmode
+ && blkmode_bitfield
+ && (*pbitpos % BITS_PER_UNIT) == 0
+ && (*pbitsize % BITS_PER_UNIT) == 0)
+ *pmode = BLKmode;
+ else
+ *pmode = mode;
return exp;
}
}
break;
- case NON_LVALUE_EXPR: case NOP_EXPR: case CONVERT_EXPR:
+ case BIT_AND_EXPR:
+ /* The highest power of two of a bit-and expression is the maximum of
+ that of its operands. We typically get here for a complex LHS and
+ a constant negative power of two on the RHS to force an explicit
+ alignment, so don't bother looking at the LHS. */
+ return highest_pow2_factor (TREE_OPERAND (exp, 1));
+
+ CASE_CONVERT:
case SAVE_EXPR:
return highest_pow2_factor (TREE_OPERAND (exp, 0));
}
ignore = (target == const0_rtx
- || ((code == NON_LVALUE_EXPR || code == NOP_EXPR
- || code == CONVERT_EXPR || code == COND_EXPR
- || code == VIEW_CONVERT_EXPR)
+ || ((code == NOP_EXPR || code == CONVERT_EXPR
+ || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
&& TREE_CODE (type) == VOID_TYPE));
/* An operation in what may be a bit-field type needs the
/* If this is a constant, put it into a register if it is a legitimate
constant, OFFSET is 0, and we won't try to extract outside the
register (in case we were passed a partially uninitialized object
- or a view_conversion to a larger size). Force the constant to
- memory otherwise. */
+ or a view_conversion to a larger size) or a BLKmode piece of it
+ (e.g. if it is unchecked-converted to a record type in Ada). Force
+ the constant to memory otherwise. */
if (CONSTANT_P (op0))
{
enum machine_mode mode = TYPE_MODE (TREE_TYPE (tem));
if (mode != BLKmode && LEGITIMATE_CONSTANT_P (op0)
&& offset == 0
+ && mode1 != BLKmode
&& bitpos + bitsize <= GET_MODE_BITSIZE (mode))
op0 = force_reg (mode, op0);
else
for an ARRAY_RANGE_REF whose type is BLKmode. */
else if (!MEM_P (op0)
&& (offset != 0
- || (bitpos + bitsize > GET_MODE_BITSIZE (GET_MODE (op0)))
- || (code == ARRAY_RANGE_REF && mode == BLKmode)))
+ || mode1 == BLKmode
+ || (bitpos + bitsize
+ > GET_MODE_BITSIZE (GET_MODE (op0)))))
{
tree nt = build_qualified_type (TREE_TYPE (tem),
(TYPE_QUALS (TREE_TYPE (tem))
return expand_call (exp, target, ignore);
case PAREN_EXPR:
- case NON_LVALUE_EXPR:
- case NOP_EXPR:
- case CONVERT_EXPR:
+ CASE_CONVERT:
if (TREE_OPERAND (exp, 0) == error_mark_node)
return const0_rtx;
if (modifier == EXPAND_STACK_PARM)
target = 0;
temp = expand_unop (mode,
- optab_for_tree_code (NEGATE_EXPR, type),
+ optab_for_tree_code (NEGATE_EXPR, type,
+ optab_default),
op0, target, 0);
gcc_assert (temp);
return REDUCE_BIT_FIELD (temp);
/* First try to do it with a special MIN or MAX instruction.
If that does not win, use a conditional jump to select the proper
value. */
- this_optab = optab_for_tree_code (code, type);
+ this_optab = optab_for_tree_code (code, type, optab_default);
temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
OPTAB_WIDEN);
if (temp != 0)
case LROTATE_EXPR:
case RROTATE_EXPR:
- /* The expansion code only handles expansion of mode precision
- rotates. */
- gcc_assert (GET_MODE_PRECISION (TYPE_MODE (type))
- == TYPE_PRECISION (type));
+ gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
+ || (GET_MODE_PRECISION (TYPE_MODE (type))
+ == TYPE_PRECISION (type)));
+ /* fall through */
- /* Falltrough. */
case LSHIFT_EXPR:
case RSHIFT_EXPR:
/* If this is a fixed-point operation, then we cannot use the code
return const0_rtx;
case EXC_PTR_EXPR:
- return get_exception_pointer (cfun);
+ return get_exception_pointer ();
case FILTER_EXPR:
- return get_exception_filter (cfun);
+ return get_exception_filter ();
case FDESC_EXPR:
/* Function descriptors are not valid except for as
tree oprnd2 = TREE_OPERAND (exp, 2);
rtx op2;
- this_optab = optab_for_tree_code (code, type);
+ this_optab = optab_for_tree_code (code, type, optab_default);
expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
op2 = expand_normal (oprnd2);
temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
case REDUC_PLUS_EXPR:
{
op0 = expand_normal (TREE_OPERAND (exp, 0));
- this_optab = optab_for_tree_code (code, type);
+ this_optab = optab_for_tree_code (code, type, optab_default);
temp = expand_unop (mode, this_optab, op0, target, unsignedp);
gcc_assert (temp);
return temp;
{
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
NULL_RTX, &op0, &op1, 0);
- this_optab = optab_for_tree_code (code, type);
+ this_optab = optab_for_tree_code (code, type, optab_default);
temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
OPTAB_WIDEN);
gcc_assert (temp);
{
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
NULL_RTX, &op0, &op1, 0);
- this_optab = optab_for_tree_code (code, type);
+ this_optab = optab_for_tree_code (code, type, optab_default);
temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
OPTAB_WIDEN);
gcc_assert (temp);
case VEC_UNPACK_LO_EXPR:
{
op0 = expand_normal (TREE_OPERAND (exp, 0));
- this_optab = optab_for_tree_code (code, type);
+ this_optab = optab_for_tree_code (code, type, optab_default);
temp = expand_widen_pattern_expr (exp, op0, NULL_RTX, NULL_RTX,
target, unsignedp);
gcc_assert (temp);
op0 = expand_normal (TREE_OPERAND (exp, 0));
/* The signedness is determined from input operand. */
this_optab = optab_for_tree_code (code,
- TREE_TYPE (TREE_OPERAND (exp, 0)));
+ TREE_TYPE (TREE_OPERAND (exp, 0)),
+ optab_default);
temp = expand_widen_pattern_expr
(exp, op0, NULL_RTX, NULL_RTX,
target, TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
subtarget, &op0, &op1, 0);
binop2:
- this_optab = optab_for_tree_code (code, type);
+ this_optab = optab_for_tree_code (code, type, optab_default);
binop3:
if (modifier == EXPAND_STACK_PARM)
target = 0;
is_aligning_offset (const_tree offset, const_tree exp)
{
/* Strip off any conversions. */
- while (TREE_CODE (offset) == NON_LVALUE_EXPR
- || TREE_CODE (offset) == NOP_EXPR
- || TREE_CODE (offset) == CONVERT_EXPR)
+ while (CONVERT_EXPR_P (offset))
offset = TREE_OPERAND (offset, 0);
/* We must now have a BIT_AND_EXPR with a constant that is one less than
/* Look at the first operand of BIT_AND_EXPR and strip any conversion.
It must be NEGATE_EXPR. Then strip any more conversions. */
offset = TREE_OPERAND (offset, 0);
- while (TREE_CODE (offset) == NON_LVALUE_EXPR
- || TREE_CODE (offset) == NOP_EXPR
- || TREE_CODE (offset) == CONVERT_EXPR)
+ while (CONVERT_EXPR_P (offset))
offset = TREE_OPERAND (offset, 0);
if (TREE_CODE (offset) != NEGATE_EXPR)
return 0;
offset = TREE_OPERAND (offset, 0);
- while (TREE_CODE (offset) == NON_LVALUE_EXPR
- || TREE_CODE (offset) == NOP_EXPR
- || TREE_CODE (offset) == CONVERT_EXPR)
+ while (CONVERT_EXPR_P (offset))
offset = TREE_OPERAND (offset, 0);
/* This must now be the address of EXP. */
{
rtx temp, vector;
- if (INTVAL (range) > cfun->max_jumptable_ents)
- cfun->max_jumptable_ents = INTVAL (range);
+ if (INTVAL (range) > cfun->cfg->max_jumptable_ents)
+ cfun->cfg->max_jumptable_ents = INTVAL (range);
/* Do an unsigned comparison (in the proper mode) between the index
expression and the value which represents the length of the range.