From 72c3b159d5de32ec8943719866338dc11a8cb026 Mon Sep 17 00:00:00 2001 From: bonzini Date: Fri, 1 Apr 2005 07:58:44 +0000 Subject: [PATCH] 2005-04-01 Paolo Bonzini Jan Hubicka * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97376 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 ++++++ gcc/config/i386/i386.c | 86 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3902558415..ab5c35f5505 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-04-01 Paolo Bonzini + Jan Hubicka + + * 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 PR c++/19406 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 80f4b0c1433..802103531d6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; -- 2.11.0