Commit 00b40d0d by Uros Bizjak Committed by Uros Bizjak

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
parent 87f53554
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> 2011-07-20 Robert Millan <rmh@gnu.org>
* config.gcc (mips*-*-linux*): Remove redundant tm_file entry. * config.gcc (mips*-*-linux*): Remove redundant tm_file entry.
...@@ -13,12 +22,11 @@ ...@@ -13,12 +22,11 @@
memory address space to the type's address space. memory address space to the type's address space.
2011-07-20 Georg-Johann Lay <avr@gjlay.de> 2011-07-20 Georg-Johann Lay <avr@gjlay.de>
PR target/36467 PR target/36467
PR target/49687 PR target/49687
* config/avr/avr.md (mulhi3): Use register_or_s9_operand for * config/avr/avr.md (mulhi3): Use register_or_s9_operand for operand2
operand2 and expand appropriately if there is a CONST_INT in and expand appropriately if there is a CONST_INT in operand2.
operand2.
(usmulqihi3): New insn. (usmulqihi3): New insn.
(*sumulqihi3): New insn. (*sumulqihi3): New insn.
(*osmulqihi3): New insn. (*osmulqihi3): New insn.
......
...@@ -11197,6 +11197,16 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) ...@@ -11197,6 +11197,16 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
else else
disp = addr; /* displacement */ 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. */ /* Extract the integral value of scale. */
if (scale_rtx) if (scale_rtx)
{ {
...@@ -11630,23 +11640,18 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, ...@@ -11630,23 +11640,18 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
disp = parts.disp; disp = parts.disp;
scale = parts.scale; scale = parts.scale;
/* Validate base register. /* 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. */
if (base) if (base)
{ {
rtx reg; rtx reg;
if (REG_P (base)) if (REG_P (base))
reg = base; reg = base;
else if (GET_CODE (base) == SUBREG else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base)))
&& REG_P (SUBREG_REG (base)) {
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (base))) reg = SUBREG_REG (base);
<= UNITS_PER_WORD) gcc_assert (register_no_elim_operand (reg, DImode));
reg = SUBREG_REG (base); }
else else
/* Base is not a register. */ /* Base is not a register. */
return false; return false;
...@@ -11660,21 +11665,18 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, ...@@ -11660,21 +11665,18 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
return false; return false;
} }
/* Validate index register. /* Validate index register. */
Don't allow SUBREG's that span more than a word here -- same as above. */
if (index) if (index)
{ {
rtx reg; rtx reg;
if (REG_P (index)) if (REG_P (index))
reg = index; reg = index;
else if (GET_CODE (index) == SUBREG else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index)))
&& REG_P (SUBREG_REG (index)) {
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (index))) reg = SUBREG_REG (index);
<= UNITS_PER_WORD) gcc_assert (register_no_elim_operand (reg, DImode));
reg = SUBREG_REG (index); }
else else
/* Index is not a register. */ /* Index is not a register. */
return false; return false;
...@@ -11688,6 +11690,11 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, ...@@ -11688,6 +11690,11 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
return false; return false;
} }
/* Index and base should have the same mode. */
if (base && index
&& GET_MODE (base) != GET_MODE (index))
return false;
/* Validate scale factor. */ /* Validate scale factor. */
if (scale != 1) if (scale != 1)
{ {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment