case SUBREG:
/* Non-paradoxical SUBREGs distributes over all operations, provided
the inner modes and word numbers are the same, this is an extraction
- of a low-order part, and we would not be converting a single-word
+ of a low-order part, we don't convert an fp operation to int or
+ vice versa, and we would not be converting a single-word
operation into a multi-word operation. The latter test is not
- required, but we prevents generating unneeded multi-word operations.
+ required, but it prevents generating unneeded multi-word operations.
Some of the previous tests are redundant given the latter test, but
are retained because they are required for correctness.
if (GET_MODE (SUBREG_REG (lhs)) != GET_MODE (SUBREG_REG (rhs))
|| SUBREG_WORD (lhs) != SUBREG_WORD (rhs)
|| ! subreg_lowpart_p (lhs)
+ || (GET_MODE_CLASS (GET_MODE (lhs))
+ != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs))))
|| (GET_MODE_SIZE (GET_MODE (lhs))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))))
|| GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
"ldos %1,%0"
[(set_attr "type" "load")])
+;; Using shifts here generates much better code than doing an `and 255'.
+;; This is mainly because the `and' requires loading the constant separately,
+;; the constant is likely to get optimized, and then the compiler can't
+;; optimize the `and' because it doesn't know that one operand is a constant.
+
(define_expand "zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
for (tv = bl->giv; tv; tv = tv->next_iv)
if (tv->giv_type == DEST_ADDR && tv->same == v)
{
- /* Increment the giv by the amount that was calculated in
- find_splittable_givs, and saved in add_val. */
- tv->dest_reg = plus_constant (tv->dest_reg,
- INTVAL (tv->add_val));
+ int this_giv_inc = INTVAL (giv_inc);
+
+ /* Scale this_giv_inc if the multiplicative factors of
+ the two givs are different. */
+ if (tv->mult_val != v->mult_val)
+ this_giv_inc = (this_giv_inc / INTVAL (v->mult_val)
+ * INTVAL (tv->mult_val));
+
+ tv->dest_reg = plus_constant (tv->dest_reg, this_giv_inc);
*tv->location = tv->dest_reg;
if (last_iteration && unroll_type != UNROLL_COMPLETELY)
}
}
- /* Overwrite the old add_val, which is no longer needed, and
- substitute the amount that the giv is incremented on each
- iteration. We need to save this somewhere, so we know how
- much to increment split DEST_ADDR giv's in copy_loop_body. */
-
- v->add_val = giv_inc;
-
if (loop_dump_stream)
fprintf (loop_dump_stream, "DEST_ADDR giv being split.\n");
}