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>
PR c++/19406
......
......@@ -4663,9 +4663,8 @@ ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
int
ix86_decompose_address (rtx addr, struct ix86_address *out)
{
rtx base = NULL_RTX;
rtx index = NULL_RTX;
rtx disp = NULL_RTX;
rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
rtx base_reg, index_reg;
HOST_WIDE_INT scale = 1;
rtx scale_rtx = NULL_RTX;
int retval = 1;
......@@ -4767,34 +4766,37 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
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. */
if (base && index && scale == 1
&& (index == arg_pointer_rtx
|| index == frame_pointer_rtx
|| (REG_P (index) && REGNO (index) == STACK_POINTER_REGNUM)))
if (base_reg && index_reg && scale == 1
&& (index_reg == arg_pointer_rtx
|| index_reg == frame_pointer_rtx
|| (REG_P (index_reg) && REGNO (index_reg) == STACK_POINTER_REGNUM)))
{
rtx tmp = base;
base = index;
index = tmp;
rtx tmp;
tmp = base, base = index, index = tmp;
tmp = base_reg, base_reg = index_reg, index_reg = tmp;
}
/* Special case: %ebp cannot be encoded as a base without a displacement. */
if ((base == hard_frame_pointer_rtx
|| base == frame_pointer_rtx
|| base == arg_pointer_rtx) && !disp)
if ((base_reg == hard_frame_pointer_rtx
|| base_reg == frame_pointer_rtx
|| base_reg == arg_pointer_rtx) && !disp)
disp = const0_rtx;
/* Special case: on K6, [%esi] makes the instruction vector decoded.
Avoid this by transforming to [%esi+0]. */
if (ix86_tune == PROCESSOR_K6 && !optimize_size
&& base && !index && !disp
&& REG_P (base)
&& REGNO_REG_CLASS (REGNO (base)) == SIREG)
&& base_reg && !index_reg && !disp
&& REG_P (base_reg)
&& REGNO_REG_CLASS (REGNO (base_reg)) == SIREG)
disp = const0_rtx;
/* Special case: encode reg+reg instead of reg*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. */
if (!base && !disp && index && scale != 1)
......@@ -4823,6 +4825,11 @@ ix86_address_cost (rtx x)
if (!ix86_decompose_address (x, &parts))
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. */
if (parts.disp && parts.disp != const0_rtx)
cost--;
......@@ -5172,15 +5179,23 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
/* Validate base register.
Don't allow SUBREG's 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. */
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)
{
rtx reg;
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";
goto report_error;
......@@ -5192,8 +5207,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
goto report_error;
}
if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
|| (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
|| (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (reg)))
{
reason = "base is not valid";
goto report_error;
......@@ -5202,15 +5217,21 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
/* Validate index register.
Don't allow SUBREG's here, it can lead to spill failures when the index
is one word out of a two word structure, which is represented internally
as a DImode int. */
Don't allow SUBREG's that span more than a word here -- same as above. */
if (index)
{
rtx reg;
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";
goto report_error;
......@@ -5222,8 +5243,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
goto report_error;
}
if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (index))
|| (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (index)))
if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
|| (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (reg)))
{
reason = "index is not valid";
goto report_error;
......@@ -11834,6 +11855,11 @@ memory_address_length (rtx addr)
if (! ix86_decompose_address (addr, &parts))
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;
index = parts.index;
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