2005-04-01 Paolo Bonzini <bonzini@gnu.org>
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Apr 2005 07:58:44 +0000 (07:58 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Apr 2005 07:58:44 +0000 (07:58 +0000)
    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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97376 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c

index e390255..ab5c35f 100644 (file)
@@ -1,3 +1,12 @@
+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
index 80f4b0c..8021035 100644 (file)
@@ -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;