summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorfroydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4>2008-02-23 01:00:42 +0000
committerfroydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4>2008-02-23 01:00:42 +0000
commite720c3f0c8224f18013942c3f5f5b86f0a9475fc (patch)
treefc8d0ee8fd48c04b14099c057f2fab16c384236c /gcc/config
parentdc3be37211952695cdf7690df2b2caf2be61bc4e (diff)
downloadgcc-e720c3f0c8224f18013942c3f5f5b86f0a9475fc.tar.gz
* config/rs6000/rs6000.c (rs6000_legitimize_address): Check to
ensure that we can address an entire entity > 8 bytes. Don't generate reg+reg addressing for such data. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132567 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/rs6000.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b3eb0550605..fb6aa19659a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3630,19 +3630,29 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
/* We accept [reg + reg] and [reg + OFFSET]. */
if (GET_CODE (x) == PLUS)
- {
- rtx op1 = XEXP (x, 0);
- rtx op2 = XEXP (x, 1);
-
- op1 = force_reg (Pmode, op1);
-
- if (GET_CODE (op2) != REG
- && (GET_CODE (op2) != CONST_INT
- || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
- op2 = force_reg (Pmode, op2);
-
- return gen_rtx_PLUS (Pmode, op1, op2);
- }
+ {
+ rtx op1 = XEXP (x, 0);
+ rtx op2 = XEXP (x, 1);
+ rtx y;
+
+ op1 = force_reg (Pmode, op1);
+
+ if (GET_CODE (op2) != REG
+ && (GET_CODE (op2) != CONST_INT
+ || !SPE_CONST_OFFSET_OK (INTVAL (op2))
+ || (GET_MODE_SIZE (mode) > 8
+ && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
+ op2 = force_reg (Pmode, op2);
+
+ /* We can't always do [reg + reg] for these, because [reg +
+ reg + offset] is not a legitimate addressing mode. */
+ y = gen_rtx_PLUS (Pmode, op1, op2);
+
+ if (GET_MODE_SIZE (mode) > 8 && REG_P (op2))
+ return force_reg (Pmode, y);
+ else
+ return y;
+ }
return force_reg (Pmode, x);
}