diff mbox

[i386] : Some more ix86_decompose_address fixes

Message ID CAFULd4a-DVP8Nmaf7fA5dgdTdM8feLRjdAmkhMez=O5725Ze0w@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Nov. 18, 2013, 6:05 p.m. UTC
Hello!

Attached patch moves remaining non-structural checks from
ix86_decompose_address to ix86_legitimate_address_p.  The patch also
introduces ix86_validate_address_register to remove some code
duplication.

2013-11-18  Uros Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.c (ix86_decompose_address): Use REG_P instead of
    ix86_address_subreg_operand.  Move subreg checks to
    ix86_validate_address_register.  Move address override check to
    ix86_legitimate_address_p.
    (ix86_validate_address_register): New function.
    (ix86_legitimate_address_p): Call ix86_validate_address_register
    to validate base and index registers.  Add address override check
    from ix86_decompose_address.
    (ix86_decompose_address): Remove.

Tested on x86_64-pc-linux-gnu {,-m32} and committed to mainline SVN.

The patch will be backported to other release branches together with
previous ix86_decompose_address patch [1].

[1] http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01977.html

Uros.
diff mbox

Patch

Index: i386.c
===================================================================
--- i386.c	(revision 204925)
+++ i386.c	(working copy)
@@ -11773,27 +11773,6 @@  ix86_live_on_entry (bitmap regs)
     }
 }
 
-/* Determine if op is suitable SUBREG RTX for address.  */
-
-static bool
-ix86_address_subreg_operand (rtx op)
-{
-  enum machine_mode mode;
-
-  if (!REG_P (op))
-    return false;
-
-  mode = GET_MODE (op);
-
-  /* Don't allow SUBREGs that span more than a word.  It can lead to spill
-     failures when the register is one word out of a two word structure.  */
-  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
-    return false;
-
-  /* Allow only SUBREGs of non-eliminable hard registers.  */
-  return register_no_elim_operand (op, mode);
-}
-
 /* Extract the parts of an RTL expression that is a valid memory address
    for an instruction.  Return 0 if the structure of the address is
    grossly off.  Return -1 if the address contains ASHIFT, so it is not
@@ -11850,7 +11829,7 @@  ix86_decompose_address (rtx addr, struct ix86_addr
     base = addr;
   else if (GET_CODE (addr) == SUBREG)
     {
-      if (ix86_address_subreg_operand (SUBREG_REG (addr)))
+      if (REG_P (SUBREG_REG (addr)))
 	base = addr;
       else
 	return 0;
@@ -11914,7 +11893,7 @@  ix86_decompose_address (rtx addr, struct ix86_addr
 	      break;
 
 	    case SUBREG:
-	      if (!ix86_address_subreg_operand (SUBREG_REG (op)))
+	      if (!REG_P (SUBREG_REG (op)))
 		return 0;
 	      /* FALLTHRU */
 
@@ -11967,18 +11946,12 @@  ix86_decompose_address (rtx addr, struct ix86_addr
       if (REG_P (index))
 	;
       else if (GET_CODE (index) == SUBREG
-	       && ix86_address_subreg_operand (SUBREG_REG (index)))
+	       && REG_P (SUBREG_REG (index)))
 	;
       else
 	return 0;
     }
 
-/* Address override works only on the (%reg) part of %fs:(%reg).  */
-  if (seg != SEG_DEFAULT
-      && ((base && GET_MODE (base) != word_mode)
-	  || (index && GET_MODE (index) != word_mode)))
-    return 0;
-
   /* Extract the integral value of scale.  */
   if (scale_rtx)
     {
@@ -12495,6 +12468,45 @@  ix86_legitimize_reload_address (rtx x,
   return false;
 }
 
+/* Determine if op is suitable RTX for an address register.
+   Return naked register if a register or a register subreg is
+   found, otherwise return NULL_RTX.  */
+
+static rtx
+ix86_validate_address_register (rtx op)
+{
+  enum machine_mode mode = GET_MODE (op);
+
+  /* Only SImode or DImode registers can form the address.  */
+  if (mode != SImode && mode != DImode)
+    return NULL_RTX;
+
+  if (REG_P (op))
+    return op;
+  else if (GET_CODE (op) == SUBREG)
+    {
+      rtx reg = SUBREG_REG (op);
+
+      if (!REG_P (reg))
+	return NULL_RTX;
+
+      mode = GET_MODE (reg);
+
+      /* Don't allow SUBREGs that span more than a word.  It can
+	 lead to spill failures when the register is one word out
+	 of a two word structure.  */
+      if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+	return NULL_RTX;
+
+      /* Allow only SUBREGs of non-eliminable hard registers.  */
+      if (register_no_elim_operand (reg, mode))
+	return reg;
+    }
+
+  /* Op is not a register.  */
+  return NULL_RTX;
+}
+
 /* Recognizes RTL expressions that are valid memory addresses for an
    instruction.  The MODE argument is the machine mode for the MEM
    expression that wants to use this address.
@@ -12510,6 +12522,7 @@  ix86_legitimate_address_p (enum machine_mode mode
   struct ix86_address parts;
   rtx base, index, disp;
   HOST_WIDE_INT scale;
+  enum ix86_address_seg seg;
 
   if (ix86_decompose_address (addr, &parts) <= 0)
     /* Decomposition failed.  */
@@ -12519,23 +12532,16 @@  ix86_legitimate_address_p (enum machine_mode mode
   index = parts.index;
   disp = parts.disp;
   scale = parts.scale;
+  seg = parts.seg;
 
   /* Validate base register.  */
   if (base)
     {
-      rtx reg;
+      rtx reg = ix86_validate_address_register (base);
 
-      if (REG_P (base))
-  	reg = base;
-      else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base)))
-	reg = SUBREG_REG (base);
-      else
-	/* Base is not a register.  */
+      if (reg == NULL_RTX)
 	return false;
 
-      if (GET_MODE (base) != SImode && GET_MODE (base) != DImode)
-	return false;
-
       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
 	  || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (reg)))
 	/* Base is not valid.  */
@@ -12545,19 +12551,11 @@  ix86_legitimate_address_p (enum machine_mode mode
   /* Validate index register.  */
   if (index)
     {
-      rtx reg;
+      rtx reg = ix86_validate_address_register (index);
 
-      if (REG_P (index))
-  	reg = index;
-      else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index)))
-	reg = SUBREG_REG (index);
-      else
-	/* Index is not a register.  */
+      if (reg == NULL_RTX)
 	return false;
 
-      if (GET_MODE (index) != SImode && GET_MODE (index) != DImode)
-	return false;
-
       if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
 	  || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (reg)))
 	/* Index is not valid.  */
@@ -12569,6 +12567,12 @@  ix86_legitimate_address_p (enum machine_mode mode
       && GET_MODE (base) != GET_MODE (index))
     return false;
 
+  /* Address override works only on the (%reg) part of %fs:(%reg).  */
+  if (seg != SEG_DEFAULT
+      && ((base && GET_MODE (base) != word_mode)
+	  || (index && GET_MODE (index) != word_mode)))
+    return false;
+
   /* Validate scale factor.  */
   if (scale != 1)
     {