aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/config/rs6000/predicates.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/config/rs6000/predicates.md')
-rw-r--r--gcc-4.9/gcc/config/rs6000/predicates.md75
1 files changed, 65 insertions, 10 deletions
diff --git a/gcc-4.9/gcc/config/rs6000/predicates.md b/gcc-4.9/gcc/config/rs6000/predicates.md
index 8c384b380..2f4046215 100644
--- a/gcc-4.9/gcc/config/rs6000/predicates.md
+++ b/gcc-4.9/gcc/config/rs6000/predicates.md
@@ -1783,7 +1783,7 @@
(define_predicate "fusion_gpr_mem_load"
(match_code "mem,sign_extend,zero_extend")
{
- rtx addr;
+ rtx addr, base, offset;
/* Handle sign/zero extend. */
if (GET_CODE (op) == ZERO_EXTEND
@@ -1813,24 +1813,79 @@
}
addr = XEXP (op, 0);
+ if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
+ return 0;
+
+ base = XEXP (addr, 0);
+ if (!base_reg_operand (base, GET_MODE (base)))
+ return 0;
+
+ offset = XEXP (addr, 1);
+
if (GET_CODE (addr) == PLUS)
+ return satisfies_constraint_I (offset);
+
+ else if (GET_CODE (addr) == LO_SUM)
{
- rtx base = XEXP (addr, 0);
- rtx offset = XEXP (addr, 1);
+ if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64))
+ return small_toc_ref (offset, GET_MODE (offset));
- return (base_reg_operand (base, GET_MODE (base))
- && satisfies_constraint_I (offset));
+ else if (TARGET_ELF && !TARGET_POWERPC64)
+ return CONSTANT_P (offset);
}
- else if (GET_CODE (addr) == LO_SUM)
+ return 0;
+})
+
+;; Match a GPR load (lbz, lhz, lwz, ld) that uses a combined address in the
+;; memory field with both the addis and the memory offset. Sign extension
+;; is not handled here, since lha and lwa are not fused.
+(define_predicate "fusion_gpr_mem_combo"
+ (match_code "mem,zero_extend")
+{
+ rtx addr, base, offset;
+
+ /* Handle zero extend. */
+ if (GET_CODE (op) == ZERO_EXTEND)
{
- rtx base = XEXP (addr, 0);
- rtx offset = XEXP (addr, 1);
+ op = XEXP (op, 0);
+ mode = GET_MODE (op);
+ }
+
+ if (!MEM_P (op))
+ return 0;
- if (!base_reg_operand (base, GET_MODE (base)))
+ switch (mode)
+ {
+ case QImode:
+ case HImode:
+ case SImode:
+ break;
+
+ case DImode:
+ if (!TARGET_POWERPC64)
return 0;
+ break;
- else if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64))
+ default:
+ return 0;
+ }
+
+ addr = XEXP (op, 0);
+ if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
+ return 0;
+
+ base = XEXP (addr, 0);
+ if (!fusion_gpr_addis (base, GET_MODE (base)))
+ return 0;
+
+ offset = XEXP (addr, 1);
+ if (GET_CODE (addr) == PLUS)
+ return satisfies_constraint_I (offset);
+
+ else if (GET_CODE (addr) == LO_SUM)
+ {
+ if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64))
return small_toc_ref (offset, GET_MODE (offset));
else if (TARGET_ELF && !TARGET_POWERPC64)