+2005-11-28 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/24997
+ * config/rs6000/rs6000.c (legitimate_indexed_address_p): Allow pattern
+ generated by reload.
+ * config/rs6000/predicates.md (indexed_or_indirect_operand): Use
+ indexed_or_indirect_address.
+ (indexed_or_indirect_address): Don't test for base reg. Call
+ address_operand last. Make it a special predicate.
+
2005-11-27 Kazu Hirata <kazu@codesourcery.com>
* config/m68k/m68k.c (notice_update_cc): Remove useless code.
|| reload_in_progress,
mode, XEXP (op, 0))")))
-;; Return 1 if the operand is an indexed or indirect memory operand.
-(define_predicate "indexed_or_indirect_operand"
- (match_operand 0 "memory_operand")
-{
- rtx tmp = XEXP (op, 0);
-
- if (TARGET_ALTIVEC
- && ALTIVEC_VECTOR_MODE (mode)
- && GET_CODE (tmp) == AND
- && GET_CODE (XEXP (tmp, 1)) == CONST_INT
- && INTVAL (XEXP (tmp, 1)) == -16)
- tmp = XEXP (tmp, 0);
-
- return REG_P (tmp)
- || (GET_CODE (tmp) == PLUS
- && REG_P (XEXP (tmp, 0))
- && REG_P (XEXP (tmp, 1)));
-})
-
;; Return 1 if the operand is a memory operand with an address divisible by 4
(define_predicate "word_offset_memref_operand"
(and (match_operand 0 "memory_operand")
|| GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT
|| INTVAL (XEXP (XEXP (op, 0), 1)) % 4 == 0")))
+;; Return 1 if the operand is an indexed or indirect memory operand.
+(define_predicate "indexed_or_indirect_operand"
+ (match_code "mem")
+{
+ op = XEXP (op, 0);
+ if (TARGET_ALTIVEC
+ && ALTIVEC_VECTOR_MODE (mode)
+ && GET_CODE (op) == AND
+ && GET_CODE (XEXP (op, 1)) == CONST_INT
+ && INTVAL (XEXP (op, 1)) == -16)
+ op = XEXP (op, 0);
+
+ return indexed_or_indirect_address (op, mode);
+})
+
;; Return 1 if the operand is an indexed or indirect address.
-(define_predicate "indexed_or_indirect_address"
- (and (match_operand 0 "address_operand")
- (match_test "REG_P (op)
+(define_special_predicate "indexed_or_indirect_address"
+ (and (match_test "REG_P (op)
|| (GET_CODE (op) == PLUS
- && REG_P (XEXP (op, 0))
- && REG_P (XEXP (op, 1)))")))
+ /* Omit testing REG_P (XEXP (op, 0)). */
+ && REG_P (XEXP (op, 1)))")
+ (match_operand 0 "address_operand")))
;; Used for the destination of the fix_truncdfsi2 expander.
;; If stfiwx will be used, the result goes to memory; otherwise,
op0 = XEXP (x, 0);
op1 = XEXP (x, 1);
- if (!REG_P (op0) || !REG_P (op1))
- return false;
-
- return ((INT_REG_OK_FOR_BASE_P (op0, strict)
- && INT_REG_OK_FOR_INDEX_P (op1, strict))
- || (INT_REG_OK_FOR_BASE_P (op1, strict)
- && INT_REG_OK_FOR_INDEX_P (op0, strict)));
+ if (REG_P (op0) && REG_P (op1))
+ return ((INT_REG_OK_FOR_BASE_P (op0, strict)
+ && INT_REG_OK_FOR_INDEX_P (op1, strict))
+ || (INT_REG_OK_FOR_BASE_P (op1, strict)
+ && INT_REG_OK_FOR_INDEX_P (op0, strict)));
+
+ /* Recognize the rtl generated by reload which we know will later be
+ replaced by a base reg. We rely on nothing but reload generating
+ this particular pattern, a reasonable assumption because it is not
+ canonical. */
+ else if (reload_in_progress
+ && GET_CODE (op0) == PLUS
+ && REG_P (XEXP (op0, 0))
+ && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && REG_P (op1))
+ return INT_REG_OK_FOR_INDEX_P (op1, strict);
+ return false;
}
inline bool