public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed, 4/7] MIPS -mcode-readable support
@ 2007-08-08 15:31 Richard Sandiford
  0 siblings, 0 replies; only message in thread
From: Richard Sandiford @ 2007-08-08 15:31 UTC (permalink / raw)
  To: gcc-patches

This is the fourth patch in the -mcode-readable series.

The SYMBOL_GP_RELATIVE case in mips_symbol_insns forgot to count
extended MIPS16 instructions as 2 instructions.  Because we're now
using more symbol types for MIPS16 -- and could probably use even
more in future, once -mabicalls -mips16 is supported -- it seemed
a good idea to put this doubling in a single place.  The patch below
does that.  I also took the opportunity to merge mips_symbolic_address_p
with mips_symbol_insns, which makes it easier to add new symbol types.

The %hi/%lo insn counts aren't yet right for the MIPS16;
that comes with the %hi/%lo support itself.

Tested as for the first patch and applied.

Richard


gcc/
	* config/mips/mips.c (mips_symbolic_address_p): Delete.
	(mips_symbol_insns_1): New function, split out from...
	(mips_symbol_insns): ...here.  Take a mode argument.  Treat loads
	and stores separately from load addresses.
	(mips_classify_address): Replace uses of mips_symbolic_address_p
	with uses of mips_symbol_insns.
	(mips_address_insns): Update calls to mips_symbol_insns.
	(mips_const_insns): Likewise.
	(mips_legitimize_address): Likewise.

Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2007-08-08 16:25:58.000000000 +0100
+++ gcc/config/mips/mips.c	2007-08-08 16:29:43.000000000 +0100
@@ -288,12 +288,11 @@ struct mips_integer_op;
 struct mips_sim;
 
 static bool mips_valid_base_register_p (rtx, enum machine_mode, int);
-static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode);
 static bool mips_classify_address (struct mips_address_info *, rtx,
 				   enum machine_mode, int);
 static bool mips_cannot_force_const_mem (rtx);
 static bool mips_use_blocks_for_constant_p (enum machine_mode, rtx);
-static int mips_symbol_insns (enum mips_symbol_type);
+static int mips_symbol_insns (enum mips_symbol_type, enum machine_mode);
 static bool mips16_unextended_reference_p (enum machine_mode mode, rtx, rtx);
 static rtx mips_force_temporary (rtx, rtx);
 static rtx mips_unspec_offset_high (rtx, rtx, rtx, enum mips_symbol_type);
@@ -1673,52 +1672,6 @@ mips_valid_base_register_p (rtx x, enum 
 }
 
 
-/* Return true if symbols of type SYMBOL_TYPE can directly address a value
-   with mode MODE.  This is used for both symbolic and LO_SUM addresses.  */
-
-static bool
-mips_symbolic_address_p (enum mips_symbol_type symbol_type,
-			 enum machine_mode mode)
-{
-  switch (symbol_type)
-    {
-    case SYMBOL_ABSOLUTE:
-    case SYMBOL_GP_RELATIVE:
-      return true;
-
-    case SYMBOL_PC_RELATIVE:
-      /* PC-relative addressing is only available for lw and ld.  */
-      return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
-
-    case SYMBOL_GOT_PAGE_OFST:
-      return true;
-
-    case SYMBOL_FORCE_TO_MEM:
-    case SYMBOL_GOT_DISP:
-      /* The address will have to be loaded from the constant pool
-	 or GOT before it is used in an address.  */
-      return false;
-
-    case SYMBOL_GOTOFF_PAGE:
-    case SYMBOL_GOTOFF_DISP:
-    case SYMBOL_GOTOFF_CALL:
-    case SYMBOL_GOTOFF_LOADGP:
-    case SYMBOL_TLS:
-    case SYMBOL_TLSGD:
-    case SYMBOL_TLSLDM:
-    case SYMBOL_DTPREL:
-    case SYMBOL_GOTTPREL:
-    case SYMBOL_TPREL:
-    case SYMBOL_64_HIGH:
-    case SYMBOL_64_MID:
-    case SYMBOL_64_LOW:
-    case SYMBOL_HALF:
-      return true;
-    }
-  gcc_unreachable ();
-}
-
-
 /* Return true if X is a valid address for machine mode MODE.  If it is,
    fill in INFO appropriately.  STRICT is true if we should only accept
    hard base registers.  */
@@ -1750,7 +1703,7 @@ mips_classify_address (struct mips_addre
       return (mips_valid_base_register_p (info->reg, mode, strict)
 	      && mips_symbolic_constant_p (info->offset, SYMBOL_CONTEXT_MEM,
 					   &info->symbol_type)
-	      && mips_symbolic_address_p (info->symbol_type, mode)
+	      && mips_symbol_insns (info->symbol_type, mode) > 0
 	      && mips_lo_relocs[info->symbol_type] != 0);
 
     case CONST_INT:
@@ -1765,7 +1718,7 @@ mips_classify_address (struct mips_addre
       info->type = ADDRESS_SYMBOLIC;
       return (mips_symbolic_constant_p (x, SYMBOL_CONTEXT_MEM,
 					&info->symbol_type)
-	      && mips_symbolic_address_p (info->symbol_type, mode)
+	      && mips_symbol_insns (info->symbol_type, mode) > 0
 	      && !mips_split_p[info->symbol_type]);
 
     default:
@@ -1831,13 +1784,13 @@ mips_use_blocks_for_constant_p (enum mac
   return !TARGET_MIPS16;
 }
 \f
-/* Return the number of instructions needed to load a symbol of the
-   given type into a register.  If valid in an address, the same number
-   of instructions are needed for loads and stores.  Treat extended
-   mips16 instructions as two instructions.  */
+/* Like mips_symbol_insns, but treat extended MIPS16 instructions as a
+   single instruction.  We rely on the fact that, in the worst case,
+   all instructions involved in a MIPS16 address calculation are usually
+   extended ones.  */
 
 static int
-mips_symbol_insns (enum mips_symbol_type type)
+mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode)
 {
   switch (type)
     {
@@ -1853,23 +1806,37 @@ mips_symbol_insns (enum mips_symbol_type
 
 	 The final address is then $at + %lo(symbol).  With 32-bit
 	 symbols we just need a preparatory lui.  */
-      return (ABI_HAS_64BIT_SYMBOLS ? 6 : 2);
+      return ABI_HAS_64BIT_SYMBOLS ? 6 : 2;
 
     case SYMBOL_GP_RELATIVE:
-    case SYMBOL_HALF:
+      /* Treat GP-relative accesses as taking a single instruction on
+	 MIPS16 too; the copy of $gp can often be shared.  */
       return 1;
 
     case SYMBOL_PC_RELATIVE:
-      /* This case is for mips16 only.  Assume we'll need an
-	 extended instruction.  */
-      return 2;
+      /* PC-relative constants can be only be used with addiupc,
+	 lwpc and ldpc.  */
+      if (mode == MAX_MACHINE_MODE
+	  || GET_MODE_SIZE (mode) == 4
+	  || GET_MODE_SIZE (mode) == 8)
+	return 1;
+
+      /* The constant must be loaded using addiupc first.  */
+      return 0;
 
     case SYMBOL_FORCE_TO_MEM:
       /* The constant must be loaded from the constant pool.  */
       return 0;
 
-    case SYMBOL_GOT_PAGE_OFST:
     case SYMBOL_GOT_DISP:
+      /* The constant will have to be loaded from the GOT before it
+	 is used in an address.  */
+      if (mode != MAX_MACHINE_MODE)
+	return 0;
+
+      /* Fall through.  */
+
+    case SYMBOL_GOT_PAGE_OFST:
       /* Unless -funit-at-a-time is in effect, we can't be sure whether
 	 the local/global classification is accurate.  See override_options
 	 for details.
@@ -1904,7 +1871,10 @@ mips_symbol_insns (enum mips_symbol_type
     case SYMBOL_DTPREL:
     case SYMBOL_GOTTPREL:
     case SYMBOL_TPREL:
-      /* Check whether the offset is a 16- or 32-bit value.  */
+    case SYMBOL_HALF:
+      /* A 16-bit constant formed by a single relocation, or a 32-bit
+	 constant formed from a high 16-bit relocation and a low 16-bit
+	 relocation.  Use mips_split_p to determine which.  */
       return mips_split_p[type] ? 2 : 1;
 
     case SYMBOL_TLS:
@@ -1914,6 +1884,22 @@ mips_symbol_insns (enum mips_symbol_type
   gcc_unreachable ();
 }
 
+/* If MODE is MAX_MACHINE_MODE, return the number of instructions needed
+   to load symbols of type TYPE into a register.  Return 0 if the given
+   type of symbol cannot be used as an immediate operand.
+
+   Otherwise, return the number of instructions needed to load or store
+   values of mode MODE to or from addresses of type TYPE.  Return 0 if
+   the given type of symbol is not valid in addresses.
+
+   In both cases, treat extended MIPS16 instructions as two instructions.  */
+
+static int
+mips_symbol_insns (enum mips_symbol_type type, enum machine_mode mode)
+{
+  return mips_symbol_insns_1 (type, mode) * (TARGET_MIPS16 ? 2 : 1);
+}
+
 /* Return true if X is a legitimate $sp-based address for mode MDOE.  */
 
 bool
@@ -1985,7 +1971,7 @@ mips_address_insns (rtx x, enum machine_
 	return factor;
 
       case ADDRESS_SYMBOLIC:
-	return factor * mips_symbol_insns (addr.symbol_type);
+	return factor * mips_symbol_insns (addr.symbol_type, mode);
       }
   return 0;
 }
@@ -2035,7 +2021,7 @@ mips_const_insns (rtx x)
 
       /* See if we can refer to X directly.  */
       if (mips_symbolic_constant_p (x, SYMBOL_CONTEXT_LEA, &symbol_type))
-	return mips_symbol_insns (symbol_type);
+	return mips_symbol_insns (symbol_type, MAX_MACHINE_MODE);
 
       /* Otherwise try splitting the constant into a base and offset.
 	 16-bit offsets can be added using an extra addiu.  Larger offsets
@@ -2056,7 +2042,8 @@ mips_const_insns (rtx x)
 
     case SYMBOL_REF:
     case LABEL_REF:
-      return mips_symbol_insns (mips_classify_symbol (x, SYMBOL_CONTEXT_LEA));
+      return mips_symbol_insns (mips_classify_symbol (x, SYMBOL_CONTEXT_LEA),
+				MAX_MACHINE_MODE);
 
     default:
       return 0;
@@ -2344,7 +2331,7 @@ mips_legitimize_address (rtx *xloc, enum
 
   /* See if the address can split into a high part and a LO_SUM.  */
   if (mips_symbolic_constant_p (*xloc, SYMBOL_CONTEXT_MEM, &symbol_type)
-      && mips_symbolic_address_p (symbol_type, mode)
+      && mips_symbol_insns (symbol_type, mode) > 0
       && mips_split_p[symbol_type])
     {
       *xloc = mips_split_symbol (0, *xloc);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-08-08 15:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-08 15:31 [committed, 4/7] MIPS -mcode-readable support Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).