REAL_VALUE_TYPE dconst1;
REAL_VALUE_TYPE dconst2;
REAL_VALUE_TYPE dconstm1;
+REAL_VALUE_TYPE dconstm2;
+REAL_VALUE_TYPE dconsthalf;
/* All references to the following fixed hard registers go through
these unique rtl objects. On machines where the frame-pointer and
h = CONST_DOUBLE_LOW (value) ^ CONST_DOUBLE_HIGH (value);
else
{
- h = real_hash (CONST_DOUBLE_REAL_VALUE (value));
+ h = real_hash (CONST_DOUBLE_REAL_VALUE (value));
/* MODE is used in the comparison, so it should be in the hash. */
h ^= GET_MODE (value);
}
mem_attrs attrs;
void **slot;
- /* If everything is the default, we can just return zero. */
+ /* If everything is the default, we can just return zero.
+ This must match what the corresponding MEM_* macros return when the
+ field is not present. */
if (alias == 0 && expr == 0 && offset == 0
&& (size == 0
|| (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
- && (align == BITS_PER_UNIT
- || (STRICT_ALIGNMENT
- && mode != BLKmode && align == GET_MODE_ALIGNMENT (mode))))
+ && (STRICT_ALIGNMENT && mode != BLKmode
+ ? align == GET_MODE_ALIGNMENT (mode) : align == BITS_PER_UNIT))
return 0;
attrs.alias = alias;
{
switch (*fmt++)
{
- case '0': /* Unused field. */
+ case '0': /* Field with unknown use. Zero it. */
+ X0EXP (rt_val, i) = NULL_RTX;
break;
case 'i': /* An integer? */
abort ();
if (check_mode && ! HARD_REGNO_MODE_OK (base_regno, GET_MODE (reg)))
abort ();
-
+#ifdef ENABLE_CHECKING
+ if (!subreg_offset_representable_p (REGNO (reg), GET_MODE (reg),
+ SUBREG_BYTE (x), mode))
+ abort ();
+#endif
/* Catch non-congruent offsets too. */
byte_offset = SUBREG_BYTE (x);
if ((byte_offset % GET_MODE_SIZE (mode)) != 0)
/* The following exposes the use of "x" to CSE. */
if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
+ && SCALAR_INT_MODE_P (GET_MODE (x))
&& ! no_new_pseudos)
return gen_lowpart (mode, force_reg (GET_MODE (x), x));
}
}
- /* If we modified OFFSET based on T, then subtract the outstanding
+ /* If we modified OFFSET based on T, then subtract the outstanding
bit position offset. Similarly, increase the size of the accessed
object to contain the negative offset. */
if (apply_bitpos)
offset_address (memref, offset, pow2)
rtx memref;
rtx offset;
- HOST_WIDE_INT pow2;
+ unsigned HOST_WIDE_INT pow2;
{
rtx new, addr = XEXP (memref, 0);
we don't know. */
MEM_ATTRS (new)
= get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
- MIN (MEM_ALIGN (memref),
- (unsigned HOST_WIDE_INT) pow2 * BITS_PER_UNIT),
+ MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
GET_MODE (new));
return new;
}
rtx tem;
rtx note, seq;
int probability;
+ rtx insn_last, insn;
+ int njumps = 0;
if (any_condjump_p (trial)
&& (note = find_reg_note (trial, REG_BR_PROB, 0)))
after = NEXT_INSN (after);
}
- if (seq)
+ if (!seq)
+ return trial;
+
+ /* Avoid infinite loop if any insn of the result matches
+ the original pattern. */
+ insn_last = seq;
+ while (1)
{
- /* Sometimes there will be only one insn in that list, this case will
- normally arise only when we want it in turn to be split (SFmode on
- the 29k is an example). */
- if (NEXT_INSN (seq) != NULL_RTX)
- {
- rtx insn_last, insn;
- int njumps = 0;
+ if (INSN_P (insn_last)
+ && rtx_equal_p (PATTERN (insn_last), pat))
+ return trial;
+ if (!NEXT_INSN (insn_last))
+ break;
+ insn_last = NEXT_INSN (insn_last);
+ }
- /* Avoid infinite loop if any insn of the result matches
- the original pattern. */
- insn_last = seq;
- while (1)
+ /* Mark labels. */
+ for (insn = insn_last; insn ; insn = PREV_INSN (insn))
+ {
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ mark_jump_label (PATTERN (insn), insn, 0);
+ njumps++;
+ if (probability != -1
+ && any_condjump_p (insn)
+ && !find_reg_note (insn, REG_BR_PROB, 0))
{
- if (INSN_P (insn_last)
- && rtx_equal_p (PATTERN (insn_last), pat))
- return trial;
- if (NEXT_INSN (insn_last) == NULL_RTX)
- break;
- insn_last = NEXT_INSN (insn_last);
+ /* We can preserve the REG_BR_PROB notes only if exactly
+ one jump is created, otherwise the machine description
+ is responsible for this step using
+ split_branch_probability variable. */
+ if (njumps != 1)
+ abort ();
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_BR_PROB,
+ GEN_INT (probability),
+ REG_NOTES (insn));
}
+ }
+ }
+
+ /* If we are splitting a CALL_INSN, look for the CALL_INSN
+ in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it. */
+ if (GET_CODE (trial) == CALL_INSN)
+ {
+ for (insn = insn_last; insn ; insn = PREV_INSN (insn))
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ CALL_INSN_FUNCTION_USAGE (insn)
+ = CALL_INSN_FUNCTION_USAGE (trial);
+ SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
+ }
+ }
- /* Mark labels. */
+ /* Copy notes, particularly those related to the CFG. */
+ for (note = REG_NOTES (trial); note; note = XEXP (note, 1))
+ {
+ switch (REG_NOTE_KIND (note))
+ {
+ case REG_EH_REGION:
insn = insn_last;
while (insn != NULL_RTX)
{
- if (GET_CODE (insn) == JUMP_INSN)
- {
- mark_jump_label (PATTERN (insn), insn, 0);
- njumps++;
- if (probability != -1
- && any_condjump_p (insn)
- && !find_reg_note (insn, REG_BR_PROB, 0))
- {
- /* We can preserve the REG_BR_PROB notes only if exactly
- one jump is created, otherwise the machine description
- is responsible for this step using
- split_branch_probability variable. */
- if (njumps != 1)
- abort ();
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_BR_PROB,
- GEN_INT (probability),
- REG_NOTES (insn));
- }
- }
-
+ if (GET_CODE (insn) == CALL_INSN
+ || (flag_non_call_exceptions
+ && may_trap_p (PATTERN (insn))))
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_EH_REGION,
+ XEXP (note, 0),
+ REG_NOTES (insn));
insn = PREV_INSN (insn);
}
+ break;
- /* If we are splitting a CALL_INSN, look for the CALL_INSN
- in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it. */
- if (GET_CODE (trial) == CALL_INSN)
+ case REG_NORETURN:
+ case REG_SETJMP:
+ case REG_ALWAYS_RETURN:
+ insn = insn_last;
+ while (insn != NULL_RTX)
{
- insn = insn_last;
- while (insn != NULL_RTX)
- {
- if (GET_CODE (insn) == CALL_INSN)
- CALL_INSN_FUNCTION_USAGE (insn)
- = CALL_INSN_FUNCTION_USAGE (trial);
-
- insn = PREV_INSN (insn);
- }
+ if (GET_CODE (insn) == CALL_INSN)
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
+ XEXP (note, 0),
+ REG_NOTES (insn));
+ insn = PREV_INSN (insn);
}
+ break;
- /* Copy notes, particularly those related to the CFG. */
- for (note = REG_NOTES (trial); note; note = XEXP (note, 1))
+ case REG_NON_LOCAL_GOTO:
+ insn = insn_last;
+ while (insn != NULL_RTX)
{
- switch (REG_NOTE_KIND (note))
- {
- case REG_EH_REGION:
- insn = insn_last;
- while (insn != NULL_RTX)
- {
- if (GET_CODE (insn) == CALL_INSN
- || (flag_non_call_exceptions
- && may_trap_p (PATTERN (insn))))
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EH_REGION,
- XEXP (note, 0),
- REG_NOTES (insn));
- insn = PREV_INSN (insn);
- }
- break;
-
- case REG_NORETURN:
- case REG_SETJMP:
- case REG_ALWAYS_RETURN:
- insn = insn_last;
- while (insn != NULL_RTX)
- {
- if (GET_CODE (insn) == CALL_INSN)
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
- XEXP (note, 0),
- REG_NOTES (insn));
- insn = PREV_INSN (insn);
- }
- break;
-
- case REG_NON_LOCAL_GOTO:
- insn = insn_last;
- while (insn != NULL_RTX)
- {
- if (GET_CODE (insn) == JUMP_INSN)
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
- XEXP (note, 0),
- REG_NOTES (insn));
- insn = PREV_INSN (insn);
- }
- break;
-
- default:
- break;
- }
+ if (GET_CODE (insn) == JUMP_INSN)
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
+ XEXP (note, 0),
+ REG_NOTES (insn));
+ insn = PREV_INSN (insn);
}
+ break;
- /* If there are LABELS inside the split insns increment the
- usage count so we don't delete the label. */
- if (GET_CODE (trial) == INSN)
- {
- insn = insn_last;
- while (insn != NULL_RTX)
- {
- if (GET_CODE (insn) == INSN)
- mark_label_nuses (PATTERN (insn));
+ default:
+ break;
+ }
+ }
- insn = PREV_INSN (insn);
- }
- }
+ /* If there are LABELS inside the split insns increment the
+ usage count so we don't delete the label. */
+ if (GET_CODE (trial) == INSN)
+ {
+ insn = insn_last;
+ while (insn != NULL_RTX)
+ {
+ if (GET_CODE (insn) == INSN)
+ mark_label_nuses (PATTERN (insn));
- tem = emit_insn_after_scope (seq, trial, INSN_SCOPE (trial));
+ insn = PREV_INSN (insn);
+ }
+ }
- delete_insn (trial);
- if (has_barrier)
- emit_barrier_after (tem);
+ tem = emit_insn_after_scope (seq, trial, INSN_SCOPE (trial));
- /* Recursively call try_split for each new insn created; by the
- time control returns here that insn will be fully split, so
- set LAST and continue from the insn after the one returned.
- We can't use next_active_insn here since AFTER may be a note.
- Ignore deleted insns, which can be occur if not optimizing. */
- for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
- if (! INSN_DELETED_P (tem) && INSN_P (tem))
- tem = try_split (PATTERN (tem), tem, 1);
- }
- /* Avoid infinite loop if the result matches the original pattern. */
- else if (rtx_equal_p (PATTERN (seq), pat))
- return trial;
- else
- {
- PATTERN (trial) = PATTERN (seq);
- INSN_CODE (trial) = -1;
- try_split (PATTERN (trial), trial, last);
- }
+ delete_insn (trial);
+ if (has_barrier)
+ emit_barrier_after (tem);
- /* Return either the first or the last insn, depending on which was
- requested. */
- return last
- ? (after ? PREV_INSN (after) : last_insn)
- : NEXT_INSN (before);
- }
+ /* Recursively call try_split for each new insn created; by the
+ time control returns here that insn will be fully split, so
+ set LAST and continue from the insn after the one returned.
+ We can't use next_active_insn here since AFTER may be a note.
+ Ignore deleted insns, which can be occur if not optimizing. */
+ for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
+ if (! INSN_DELETED_P (tem) && INSN_P (tem))
+ tem = try_split (PATTERN (tem), tem, 1);
- return trial;
+ /* Return either the first or the last insn, depending on which was
+ requested. */
+ return last
+ ? (after ? PREV_INSN (after) : last_insn)
+ : NEXT_INSN (before);
}
\f
/* Make and return an INSN rtx, initializing all its slots.
REAL_VALUE_FROM_INT (dconst1, 1, 0, double_mode);
REAL_VALUE_FROM_INT (dconst2, 2, 0, double_mode);
REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode);
+ REAL_VALUE_FROM_INT (dconstm2, -2, -1, double_mode);
+
+ dconsthalf = dconst1;
+ dconsthalf.exp--;
for (i = 0; i <= 2; i++)
{