rtx, unsigned int,
enum machine_mode));
static tree component_ref_for_mem_expr PARAMS ((tree));
+static rtx gen_const_vector_0 PARAMS ((enum machine_mode));
/* Probability of the conditional branch currently proceeded by try_split.
Set to -1 otherwise. */
&& (size == 0
|| (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
&& (align == BITS_PER_UNIT
- || (mode != BLKmode && align == GET_MODE_ALIGNMENT (mode))))
+ || (STRICT_ALIGNMENT
+ && mode != BLKmode && align == GET_MODE_ALIGNMENT (mode))))
return 0;
attrs.alias = alias;
if (regno == RETURN_ADDRESS_POINTER_REGNUM)
return return_address_pointer_rtx;
#endif
+ if (regno == PIC_OFFSET_TABLE_REGNUM
+ && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
+ return pic_offset_table_rtx;
if (regno == STACK_POINTER_REGNUM)
return stack_pointer_rtx;
}
low = INTVAL (x), high = low >> (HOST_BITS_PER_WIDE_INT -1);
else
low = CONST_DOUBLE_LOW (x), high = CONST_DOUBLE_HIGH (x);
-
#ifdef HOST_WORDS_BIG_ENDIAN
u.i[0] = high, u.i[1] = low;
#else
u.i[0] = low, u.i[1] = high;
#endif
-
return CONST_DOUBLE_FROM_REAL_VALUE (u.d, mode);
}
high = CONST_DOUBLE_HIGH (x);
}
+#if HOST_BITS_PER_WIDE_INT == 32
/* REAL_VALUE_TARGET_DOUBLE takes the addressing order of the
target machine. */
if (WORDS_BIG_ENDIAN)
i[0] = high, i[1] = low;
else
i[0] = low, i[1] = high;
+#else
+ i[0] = low;
+#endif
r = REAL_VALUE_FROM_TARGET_DOUBLE (i);
return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
/* simplify_gen_subreg is not guaranteed to return a valid operand for
the target if we have a MEM. gen_highpart must return a valid operand,
emitting code if necessary to do so. */
- if (GET_CODE (result) == MEM)
+ if (result != NULL_RTX && GET_CODE (result) == MEM)
result = validize_mem (result);
if (!result)
rtx offset;
HOST_WIDE_INT pow2;
{
- rtx new = change_address_1 (memref, VOIDmode,
- gen_rtx_PLUS (Pmode, XEXP (memref, 0),
- force_reg (Pmode, offset)), 1);
+ rtx new, addr = XEXP (memref, 0);
+
+ new = simplify_gen_binary (PLUS, Pmode, addr, offset);
+
+ /* At this point we don't know _why_ the address is invalid. It
+ could have secondary memory refereces, multiplies or anything.
+
+ However, if we did go and rearrange things, we can wind up not
+ being able to recognize the magic around pic_offset_table_rtx.
+ This stuff is fragile, and is yet another example of why it is
+ bad to expose PIC machinery too early. */
+ if (! memory_address_p (GET_MODE (memref), new)
+ && GET_CODE (addr) == PLUS
+ && XEXP (addr, 0) == pic_offset_table_rtx)
+ {
+ addr = force_reg (GET_MODE (addr), addr);
+ new = simplify_gen_binary (PLUS, Pmode, addr, offset);
+ }
+
+ new = change_address_1 (memref, VOIDmode, new, 1);
/* Update the alignment to reflect the offset. Reset the offset, which
we don't know. */
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
&& (bb = BLOCK_FOR_INSN (after)))
{
set_block_for_insn (insn, bb);
+ if (INSN_P (insn))
+ bb->flags |= BB_DIRTY;
/* Should not happen as first in the BB is always
either NOTE or LABEL. */
if (bb->end == after
&& (bb = BLOCK_FOR_INSN (before)))
{
set_block_for_insn (insn, bb);
+ if (INSN_P (insn))
+ bb->flags |= BB_DIRTY;
/* Should not happen as first in the BB is always
either NOTE or LABEl. */
if (bb->head == insn
&& (unsigned int)INSN_UID (insn) < basic_block_for_insn->num_elements
&& (bb = BLOCK_FOR_INSN (insn)))
{
+ if (INSN_P (insn))
+ bb->flags |= BB_DIRTY;
if (bb->head == insn)
{
/* Never ever delete the basic block note without deleting whole basic
&& (bb = BLOCK_FOR_INSN (after)))
{
rtx x;
+ bb->flags |= BB_DIRTY;
if (basic_block_for_insn
&& (unsigned int)INSN_UID (from) < basic_block_for_insn->num_elements
{
if (bb2->end == to)
bb2->end = prev;
+ bb2->flags |= BB_DIRTY;
}
if (bb->end == after)
switch (NOTE_LINE_NUMBER (insn))
{
case NOTE_INSN_DELETED:
+ case NOTE_INSN_LOOP_END_TOP_COND:
remove_insn (insn);
break;
&& (unsigned int)INSN_UID (after) < basic_block_for_insn->num_elements
&& (bb = BLOCK_FOR_INSN (after)))
{
+ bb->flags |= BB_DIRTY;
for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
set_block_for_insn (last, bb);
set_block_for_insn (last, bb);
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
ggc_mark_rtx (es->x_first_insn);
}
+/* Generate the constant 0. */
+
+static rtx
+gen_const_vector_0 (mode)
+ enum machine_mode mode;
+{
+ rtx tem;
+ rtvec v;
+ int units, i;
+ enum machine_mode inner;
+
+ units = GET_MODE_NUNITS (mode);
+ inner = GET_MODE_INNER (mode);
+
+ v = rtvec_alloc (units);
+
+ /* We need to call this function after we to set CONST0_RTX first. */
+ if (!CONST0_RTX (inner))
+ abort ();
+
+ for (i = 0; i < units; ++i)
+ RTVEC_ELT (v, i) = CONST0_RTX (inner);
+
+ tem = gen_rtx_CONST_VECTOR (mode, v);
+ return tem;
+}
+
/* Create some permanent unique rtl objects shared between all functions.
LINE_NUMBERS is nonzero if line numbers are to be generated. */
const_tiny_rtx[i][(int) mode] = GEN_INT (i);
}
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ const_tiny_rtx[0][(int) mode] = gen_const_vector_0 (mode);
+
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ const_tiny_rtx[0][(int) mode] = gen_const_vector_0 (mode);
+
for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)
if (GET_MODE_CLASS ((enum machine_mode) i) == MODE_CC)
const_tiny_rtx[0][i] = const0_rtx;
#endif
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
- pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
+ pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
ggc_add_rtx_root (&pic_offset_table_rtx, 1);
ggc_add_rtx_root (&struct_value_rtx, 1);