Commit 7c93c2cc by Paolo Bonzini Committed by Paolo Bonzini

i386.c (ix86_decompose_address): Look inside SUBREGs to fix addresses involving EBP and ESP.

2005-04-01  Paolo Bonzini  <bonzini@gnu.org>
	    Jan Hubicka  <jh@suse.cz>

	* config/i386/i386.c (ix86_decompose_address): Look inside SUBREGs
	to fix addresses involving EBP and ESP.
	(aligned_operand, legitimate_address_p, ix86_address_cost): Be prepared
	for SUBREGed registers.
	(legitimate_address_p): Accept SUBREGed registers.

Co-Authored-By: Jan Hubicka <jh@suse.cz>

From-SVN: r97376
parent a288c5cd
2005-04-01 Paolo Bonzini <bonzini@gnu.org>
Jan Hubicka <jh@suse.cz>
* config/i386/i386.c (ix86_decompose_address): Look inside SUBREGs
to fix addresses involving EBP and ESP.
(aligned_operand, legitimate_address_p, ix86_address_cost): Be prepared
for SUBREGed registers.
(legitimate_address_p): Accept SUBREGed registers.
2005-04-01 Jakub Jelinek <jakub@redhat.com> 2005-04-01 Jakub Jelinek <jakub@redhat.com>
PR c++/19406 PR c++/19406
......
...@@ -4663,9 +4663,8 @@ ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED, ...@@ -4663,9 +4663,8 @@ ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
int int
ix86_decompose_address (rtx addr, struct ix86_address *out) ix86_decompose_address (rtx addr, struct ix86_address *out)
{ {
rtx base = NULL_RTX; rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
rtx index = NULL_RTX; rtx base_reg, index_reg;
rtx disp = NULL_RTX;
HOST_WIDE_INT scale = 1; HOST_WIDE_INT scale = 1;
rtx scale_rtx = NULL_RTX; rtx scale_rtx = NULL_RTX;
int retval = 1; int retval = 1;
...@@ -4767,34 +4766,37 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) ...@@ -4767,34 +4766,37 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
scale = INTVAL (scale_rtx); scale = INTVAL (scale_rtx);
} }
base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
/* Allow arg pointer and stack pointer as index if there is not scaling. */ /* Allow arg pointer and stack pointer as index if there is not scaling. */
if (base && index && scale == 1 if (base_reg && index_reg && scale == 1
&& (index == arg_pointer_rtx && (index_reg == arg_pointer_rtx
|| index == frame_pointer_rtx || index_reg == frame_pointer_rtx
|| (REG_P (index) && REGNO (index) == STACK_POINTER_REGNUM))) || (REG_P (index_reg) && REGNO (index_reg) == STACK_POINTER_REGNUM)))
{ {
rtx tmp = base; rtx tmp;
base = index; tmp = base, base = index, index = tmp;
index = tmp; tmp = base_reg, base_reg = index_reg, index_reg = tmp;
} }
/* Special case: %ebp cannot be encoded as a base without a displacement. */ /* Special case: %ebp cannot be encoded as a base without a displacement. */
if ((base == hard_frame_pointer_rtx if ((base_reg == hard_frame_pointer_rtx
|| base == frame_pointer_rtx || base_reg == frame_pointer_rtx
|| base == arg_pointer_rtx) && !disp) || base_reg == arg_pointer_rtx) && !disp)
disp = const0_rtx; disp = const0_rtx;
/* Special case: on K6, [%esi] makes the instruction vector decoded. /* Special case: on K6, [%esi] makes the instruction vector decoded.
Avoid this by transforming to [%esi+0]. */ Avoid this by transforming to [%esi+0]. */
if (ix86_tune == PROCESSOR_K6 && !optimize_size if (ix86_tune == PROCESSOR_K6 && !optimize_size
&& base && !index && !disp && base_reg && !index_reg && !disp
&& REG_P (base) && REG_P (base_reg)
&& REGNO_REG_CLASS (REGNO (base)) == SIREG) && REGNO_REG_CLASS (REGNO (base_reg)) == SIREG)
disp = const0_rtx; disp = const0_rtx;
/* Special case: encode reg+reg instead of reg*2. */ /* Special case: encode reg+reg instead of reg*2. */
if (!base && index && scale && scale == 2) if (!base && index && scale && scale == 2)
base = index, scale = 1; base = index, base_reg = index_reg, scale = 1;
/* Special case: scaling cannot be encoded without base or displacement. */ /* Special case: scaling cannot be encoded without base or displacement. */
if (!base && !disp && index && scale != 1) if (!base && !disp && index && scale != 1)
...@@ -4823,6 +4825,11 @@ ix86_address_cost (rtx x) ...@@ -4823,6 +4825,11 @@ ix86_address_cost (rtx x)
if (!ix86_decompose_address (x, &parts)) if (!ix86_decompose_address (x, &parts))
abort (); abort ();
if (parts.base && GET_CODE (parts.base) == SUBREG)
parts.base = SUBREG_REG (parts.base);
if (parts.index && GET_CODE (parts.index) == SUBREG)
parts.index = SUBREG_REG (parts.index);
/* More complex memory references are better. */ /* More complex memory references are better. */
if (parts.disp && parts.disp != const0_rtx) if (parts.disp && parts.disp != const0_rtx)
cost--; cost--;
...@@ -5172,15 +5179,23 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict) ...@@ -5172,15 +5179,23 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
/* Validate base register. /* Validate base register.
Don't allow SUBREG's here, it can lead to spill failures when the base Don't allow SUBREG's that span more than a word here. It can lead to spill
is one word out of a two word structure, which is represented internally failures when the base is one word out of a two word structure, which is
as a DImode int. */ represented internally as a DImode int. */
if (base) if (base)
{ {
rtx reg;
reason_rtx = base; reason_rtx = base;
if (GET_CODE (base) != 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
{ {
reason = "base is not a register"; reason = "base is not a register";
goto report_error; goto report_error;
...@@ -5192,8 +5207,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict) ...@@ -5192,8 +5207,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
goto report_error; goto report_error;
} }
if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base)) if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
|| (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base))) || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (reg)))
{ {
reason = "base is not valid"; reason = "base is not valid";
goto report_error; goto report_error;
...@@ -5202,15 +5217,21 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict) ...@@ -5202,15 +5217,21 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
/* Validate index register. /* Validate index register.
Don't allow SUBREG's here, it can lead to spill failures when the index Don't allow SUBREG's that span more than a word here -- same as above. */
is one word out of a two word structure, which is represented internally
as a DImode int. */
if (index) if (index)
{ {
rtx reg;
reason_rtx = index; reason_rtx = index;
if (GET_CODE (index) != 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
{ {
reason = "index is not a register"; reason = "index is not a register";
goto report_error; goto report_error;
...@@ -5222,8 +5243,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict) ...@@ -5222,8 +5243,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
goto report_error; goto report_error;
} }
if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (index)) if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
|| (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (index))) || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (reg)))
{ {
reason = "index is not valid"; reason = "index is not valid";
goto report_error; goto report_error;
...@@ -11834,6 +11855,11 @@ memory_address_length (rtx addr) ...@@ -11834,6 +11855,11 @@ memory_address_length (rtx addr)
if (! ix86_decompose_address (addr, &parts)) if (! ix86_decompose_address (addr, &parts))
abort (); abort ();
if (parts.base && GET_CODE (parts.base) == SUBREG)
parts.base = SUBREG_REG (parts.base);
if (parts.index && GET_CODE (parts.index) == SUBREG)
parts.index = SUBREG_REG (parts.index);
base = parts.base; base = parts.base;
index = parts.index; index = parts.index;
disp = parts.disp; disp = parts.disp;
......
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