From 00b40d0da26a32c18f696c8f301b51f55960d155 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 20 Jul 2011 23:43:38 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 16 ++++++++++---- gcc/config/i386/i386.c | 47 ++++++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a33530ab705..0451e1bd739 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-07-20 Uros Bizjak + + * 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 * 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 - + 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 22f756b47fd..fbebd4c48cb 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) { -- 2.30.2