aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2011-07-20 23:43:38 +0200
committerUros Bizjak <uros@gcc.gnu.org>2011-07-20 23:43:38 +0200
commit00b40d0da26a32c18f696c8f301b51f55960d155 (patch)
tree60a4c9cc32d02505deb16553b1575c7a5eba5f2e /gcc
parent87f5355496a23915469b71b0292ab04377cf0ebd (diff)
downloadgcc-00b40d0da26a32c18f696c8f301b51f55960d155.zip
gcc-00b40d0da26a32c18f696c8f301b51f55960d155.tar.gz
gcc-00b40d0da26a32c18f696c8f301b51f55960d155.tar.bz2
i386.c (ix86_decompose_address): Allow only subregs of DImode hard registers in index.
* config/i386/i386.c (ix86_decompose_address): Allow only subregs of DImode hard registers in index. (ix86_legitimate_address_p): Allow subregs of base and index to span more than a word. Assert that subregs of base and index satisfy register_no_elim_operand predicates. Reject addresses where base and index have different modes. From-SVN: r176536
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/i386/i386.c47
2 files changed, 39 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a33530a..0451e1b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2011-07-20 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.c (ix86_decompose_address): Allow only subregs
+ of DImode hard registers in index.
+ (ix86_legitimate_address_p): Allow subregs of base and index to span
+ more than a word. Assert that subregs of base and index satisfy
+ register_no_elim_operand predicates. Reject addresses where
+ base and index have different modes.
+
2011-07-20 Robert Millan <rmh@gnu.org>
* config.gcc (mips*-*-linux*): Remove redundant tm_file entry.
@@ -13,12 +22,11 @@
memory address space to the type's address space.
2011-07-20 Georg-Johann Lay <avr@gjlay.de>
-
+
PR target/36467
PR target/49687
- * config/avr/avr.md (mulhi3): Use register_or_s9_operand for
- operand2 and expand appropriately if there is a CONST_INT in
- operand2.
+ * config/avr/avr.md (mulhi3): Use register_or_s9_operand for operand2
+ and expand appropriately if there is a CONST_INT in operand2.
(usmulqihi3): New insn.
(*sumulqihi3): New insn.
(*osmulqihi3): New insn.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 22f756b..fbebd4c4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11197,6 +11197,16 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
else
disp = addr; /* displacement */
+ if (index)
+ {
+ if (REG_P (index))
+ ;
+ /* Allow only subregs of DImode hard regs. */
+ else if (GET_CODE (index) == SUBREG
+ && !register_no_elim_operand (SUBREG_REG (index), DImode))
+ return 0;
+ }
+
/* Extract the integral value of scale. */
if (scale_rtx)
{
@@ -11630,23 +11640,18 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
disp = parts.disp;
scale = parts.scale;
- /* Validate base register.
-
- Don't allow SUBREG's that span more than a word here. It can lead to spill
- failures when the base is one word out of a two word structure, which is
- represented internally as a DImode int. */
-
+ /* Validate base register. */
if (base)
{
rtx reg;
if (REG_P (base))
reg = base;
- else if (GET_CODE (base) == SUBREG
- && REG_P (SUBREG_REG (base))
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (base)))
- <= UNITS_PER_WORD)
- reg = SUBREG_REG (base);
+ else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base)))
+ {
+ reg = SUBREG_REG (base);
+ gcc_assert (register_no_elim_operand (reg, DImode));
+ }
else
/* Base is not a register. */
return false;
@@ -11660,21 +11665,18 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
return false;
}
- /* Validate index register.
-
- Don't allow SUBREG's that span more than a word here -- same as above. */
-
+ /* Validate index register. */
if (index)
{
rtx reg;
if (REG_P (index))
reg = index;
- else if (GET_CODE (index) == SUBREG
- && REG_P (SUBREG_REG (index))
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (index)))
- <= UNITS_PER_WORD)
- reg = SUBREG_REG (index);
+ else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index)))
+ {
+ reg = SUBREG_REG (index);
+ gcc_assert (register_no_elim_operand (reg, DImode));
+ }
else
/* Index is not a register. */
return false;
@@ -11688,6 +11690,11 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
return false;
}
+ /* Index and base should have the same mode. */
+ if (base && index
+ && GET_MODE (base) != GET_MODE (index))
+ return false;
+
/* Validate scale factor. */
if (scale != 1)
{