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

I'm about to post a series of patches whose final objective is to
add a -mcode-readable option to the MIPS backend:

`-mcode-readable=SETTING'
     Specify whether GCC may generate code that reads from executable
     sections.  There are three possible settings:
   
    `-mcode-readable=yes'
          Instructions may freely access executable sections.  This is
          the default setting.
   
    `-mcode-readable=pcrel'
          MIPS16 PC-relative load instructions can access executable
          sections, but other instructions must not do so.  This option
          is useful on 4KSc and 4KSd processors when the code TLBs have
          the Read Inhibit bit set.  It is also useful on processors
          that can be configured to have a dual instruction/data SRAM
          interface and that, like the M4K, automatically redirect
          PC-relative loads to the instruction RAM.

    `-mcode-readable=no'
          Instructions must not access executable sections.  This
          option can be useful on targets that are configured to have a
          dual instruction/data SRAM interface but that (unlike the
          M4K) do not automatically redirect PC-relative loads to the
          instruction RAM.

-mcode-readable=no breaks two fairly fundamental assumptions in the MIPS16
part of the backend:

  (1) that references to the constant pool will be rewritten as
      PC-relative references to an in-function "minipool".

  (2) that symbols outside the range of a PC-relative or GP-relative
      access should be forced into the constant pool and loaded from
      there.

The rewrite described in (1) is not possible with -mcode-readable=no; we
must leave the constants in the read-only data section and address them
using %hi and %lo.  And because of that, the behaviour described in (2)
is no longer desirable; it's better to use %hi and %lo to calculate the
symbol directly than it is to force the symbol into memory and use %hi
and %lo to calculate the address of that memory.

At the moment, we use SYMBOL_GENERAL for both non-MIPS16 %hi/%lo-style
accesses and for symbols that MIPS16 code should load from the constant
pool.  Now that we need %hi and %lo for MIPS16 as well, it seems better
to move the existing MIPS16 treatment of SYMBOL_GENERAL to a new
SYMBOL_* value.

The original (3.4) symbol-classification code used properties of either
the symbols themselves or the things they refer to.  For example, we had
types like SYMBOL_SMALL_DATA, SYMBOL_CONSTANT_POOL and SYMBOL_GOT_GLOBAL.

However, things have got (even) more complicated since then, and that
choice of classification seems to have been a bad one.  It became
necessary to replace the SYMBOL_GOT_GLOBAL and SYMBOL_GOT_LOCAL types
with SYMBOL_GOT_PAGE_OFST and SYMBOL_GOT_DISP; in other words, to replace
something that classifies the symbol itself with something that classifies
the type of access.  The new MIPS16 symbol classification takes us even
further down the road of classifying based on access type.

This patch therefore completes the transition started with
SYMBOL_GOT_PAGE_OFST and SYMBOL_GOT_DISP.  It replaces:

    SYMBOL_GENERAL with SYMBOL_ABSOLUTE
    SYMBOL_SMALL_DATA with SYMBOL_GP_RELATIVE
    SYMBOL_CONSTANT_POOL with SYMBOL_PC_RELATIVE

I regression-tested this series of patches on mipsisa64-elfoabi.
I also built a mipsisa32r2-elf configuration before and after the
patches and compared the assembly code for the C and C++ testsuites
given the following options:

    -O -G8 -mips32r2 -mabi=32
    -O -G8 -mips64 -mabi=n32
    -O -G8 -mips64 -mabi=64
    -O -G0 -mips32r2 -mabi=32
    -O -G0 -mips64 -mabi=n32
    -O -G0 -mips64 -mabi=64
    -O -G0 -mabicalls -mips32r2 -mabi=32
    -O -G0 -mabicalls -mips64 -mabi=n32
    -O -G0 -mabicalls -mips64 -mabi=64
    -O -G8 -mips16 -mips32r2 -mabi=32
    -O -G8 -mips16 -mips64 -mabi=o64
    -O -G0 -mips16 -mips32r2 -mabi=32
    -O -G0 -mips16 -mips64 -mabi=o64

As expected, there were no differences; the patches are only supposed
to have an effect when the new modes are selected.  I also checked
that the mipsisa64-elfoabi test results were the same for all three
-mcode-readable options, except that -mcode-readable=no has one less
libstdc++ ICE.  (This ICE is a long-standing bug.)

All this testing was done with the patch for 32897:

    http://gcc.gnu.org/ml/gcc-patches/2007-07/msg01904.html

Applied.

Richard


gcc/
	* config/mips/mips-protos.h (SYMBOL_GENERAL): Rename to...
	(SYMBOL_ABSOLUTE): ...this.
	(SYMBOL_SMALL_DATA): Rename to...
	(SYMBOL_GP_RELATIVE): ...this.
	(SYMBOL_CONSTANT_POOL): Rename to...
	(SYMBOL_PC_RELATIVE): ...this.
	* config/mips/mips.c (mips_classify_symbol, mips_symbolic_constant_p)
	(mips_symbolic_address_p, mips_symbol_insns, override_options)
	(mips_rewrite_small_data_p, mips_use_anchors_for_symbol_p): Update
	after above changes.
	* config/mips/predicates.md (const_call_insn_operand): Likewise.
	(general_symbolic_operand): Rename to...
	(absolute_symbolic_operand): ...this.
	* config/mips/mips.md: Update after above changes.

Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h.orig	2007-08-03 17:05:20.000000000 +0100
+++ gcc/config/mips/mips-protos.h	2007-08-03 17:05:22.000000000 +0100
@@ -27,14 +27,17 @@ along with GCC; see the file COPYING3.  
 
 /* Classifies a SYMBOL_REF, LABEL_REF or UNSPEC address.
 
-   SYMBOL_GENERAL
-       Used when none of the below apply.
-
-   SYMBOL_SMALL_DATA
-       The symbol refers to something in a small data section.
-
-   SYMBOL_CONSTANT_POOL
-       The symbol refers to something in the mips16 constant pool.
+   SYMBOL_ABSOLUTE
+       The symbol's value will be calculated using absolute relocations,
+       such as %hi and %lo.
+
+   SYMBOL_GP_RELATIVE
+       The symbol's value will be calculated by adding a 16-bit offset
+       from $gp.
+
+   SYMBOL_PC_RELATIVE
+       The symbol's value will be calculated using a MIPS16 PC-relative
+       calculation.
 
    SYMBOL_GOT_PAGE_OFST
        The symbol's value will be calculated by loading an address
@@ -87,9 +90,9 @@ along with GCC; see the file COPYING3.  
        An UNSPEC wrapper around any kind of address.  It represents the
        low 16 bits of that address.  */
 enum mips_symbol_type {
-  SYMBOL_GENERAL,
-  SYMBOL_SMALL_DATA,
-  SYMBOL_CONSTANT_POOL,
+  SYMBOL_ABSOLUTE,
+  SYMBOL_GP_RELATIVE,
+  SYMBOL_PC_RELATIVE,
   SYMBOL_GOT_PAGE_OFST,
   SYMBOL_GOT_DISP,
   SYMBOL_GOTOFF_PAGE,
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c.orig	2007-08-03 17:05:20.000000000 +0100
+++ gcc/config/mips/mips.c	2007-08-03 17:05:22.000000000 +0100
@@ -1446,10 +1446,10 @@ mips_classify_symbol (rtx x)
   if (GET_CODE (x) == LABEL_REF)
     {
       if (TARGET_MIPS16)
-	return SYMBOL_CONSTANT_POOL;
+	return SYMBOL_PC_RELATIVE;
       if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
 	return SYMBOL_GOT_PAGE_OFST;
-      return SYMBOL_GENERAL;
+      return SYMBOL_ABSOLUTE;
     }
 
   gcc_assert (GET_CODE (x) == SYMBOL_REF);
@@ -1460,25 +1460,25 @@ mips_classify_symbol (rtx x)
   if (CONSTANT_POOL_ADDRESS_P (x))
     {
       if (TARGET_MIPS16)
-	return SYMBOL_CONSTANT_POOL;
+	return SYMBOL_PC_RELATIVE;
 
       if (!TARGET_EMBEDDED_DATA
 	  && GET_MODE_SIZE (get_pool_mode (x)) <= mips_section_threshold)
-	return SYMBOL_SMALL_DATA;
+	return SYMBOL_GP_RELATIVE;
     }
 
   /* Do not use small-data accesses for weak symbols; they may end up
      being zero.  */
   if (SYMBOL_REF_SMALL_P (x)
       && !SYMBOL_REF_WEAK (x))
-    return SYMBOL_SMALL_DATA;
+    return SYMBOL_GP_RELATIVE;
 
   if (TARGET_ABICALLS)
     {
       /* Don't use GOT accesses for locally-binding symbols; we can use
 	 %hi and %lo instead.  */
       if (TARGET_ABSOLUTE_ABICALLS && mips_symbol_binds_local_p (x))
-	return SYMBOL_GENERAL;
+	return SYMBOL_ABSOLUTE;
 
       /* There are three cases to consider:
 
@@ -1505,7 +1505,7 @@ mips_classify_symbol (rtx x)
       return SYMBOL_GOT_PAGE_OFST;
     }
 
-  return SYMBOL_GENERAL;
+  return SYMBOL_ABSOLUTE;
 }
 
 /* Return true if OFFSET is within the range [0, ALIGN), where ALIGN
@@ -1559,7 +1559,7 @@ mips_symbolic_constant_p (rtx x, enum mi
      relocations.  */
   switch (*symbol_type)
     {
-    case SYMBOL_GENERAL:
+    case SYMBOL_ABSOLUTE:
     case SYMBOL_64_HIGH:
     case SYMBOL_64_MID:
     case SYMBOL_64_LOW:
@@ -1573,7 +1573,7 @@ mips_symbolic_constant_p (rtx x, enum mi
       /* In other cases the relocations can handle any offset.  */
       return true;
 
-    case SYMBOL_CONSTANT_POOL:
+    case SYMBOL_PC_RELATIVE:
       /* Allow constant pool references to be converted to LABEL+CONSTANT.
 	 In this case, we no longer have access to the underlying constant,
 	 but the original symbol-based access was known to be valid.  */
@@ -1582,7 +1582,7 @@ mips_symbolic_constant_p (rtx x, enum mi
 
       /* Fall through.  */
 
-    case SYMBOL_SMALL_DATA:
+    case SYMBOL_GP_RELATIVE:
       /* Make sure that the offset refers to something within the
 	 same object block.  This should guarantee that the final
 	 PC- or GP-relative offset is within the 16-bit limit.  */
@@ -1681,13 +1681,13 @@ mips_symbolic_address_p (enum mips_symbo
 {
   switch (symbol_type)
     {
-    case SYMBOL_GENERAL:
+    case SYMBOL_ABSOLUTE:
       return !TARGET_MIPS16;
 
-    case SYMBOL_SMALL_DATA:
+    case SYMBOL_GP_RELATIVE:
       return true;
 
-    case SYMBOL_CONSTANT_POOL:
+    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;
 
@@ -1838,7 +1838,7 @@ mips_symbol_insns (enum mips_symbol_type
 {
   switch (type)
     {
-    case SYMBOL_GENERAL:
+    case SYMBOL_ABSOLUTE:
       /* In mips16 code, general symbols must be fetched from the
 	 constant pool.  */
       if (TARGET_MIPS16)
@@ -1857,11 +1857,11 @@ mips_symbol_insns (enum mips_symbol_type
 	 symbols we just need a preparatory lui.  */
       return (ABI_HAS_64BIT_SYMBOLS ? 6 : 2);
 
-    case SYMBOL_SMALL_DATA:
+    case SYMBOL_GP_RELATIVE:
     case SYMBOL_HALF:
       return 1;
 
-    case SYMBOL_CONSTANT_POOL:
+    case SYMBOL_PC_RELATIVE:
       /* This case is for mips16 only.  Assume we'll need an
 	 extended instruction.  */
       return 2;
@@ -5429,32 +5429,32 @@ override_options (void)
 	  mips_hi_relocs[SYMBOL_64_LOW] = "%hi(";
 	  mips_lo_relocs[SYMBOL_64_LOW] = "%lo(";
 
-	  mips_split_p[SYMBOL_GENERAL] = true;
-	  mips_lo_relocs[SYMBOL_GENERAL] = "%lo(";
+	  mips_split_p[SYMBOL_ABSOLUTE] = true;
+	  mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
 	}
     }
   else
     {
       if (TARGET_EXPLICIT_RELOCS || mips_split_addresses)
 	{
-	  mips_split_p[SYMBOL_GENERAL] = true;
-	  mips_hi_relocs[SYMBOL_GENERAL] = "%hi(";
-	  mips_lo_relocs[SYMBOL_GENERAL] = "%lo(";
+	  mips_split_p[SYMBOL_ABSOLUTE] = true;
+	  mips_hi_relocs[SYMBOL_ABSOLUTE] = "%hi(";
+	  mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
 	}
     }
 
   if (TARGET_MIPS16)
     {
       /* The high part is provided by a pseudo copy of $gp.  */
-      mips_split_p[SYMBOL_SMALL_DATA] = true;
-      mips_lo_relocs[SYMBOL_SMALL_DATA] = "%gprel(";
+      mips_split_p[SYMBOL_GP_RELATIVE] = true;
+      mips_lo_relocs[SYMBOL_GP_RELATIVE] = "%gprel(";
     }
 
   if (TARGET_EXPLICIT_RELOCS)
     {
       /* Small data constants are kept whole until after reload,
 	 then lowered by mips_rewrite_small_data.  */
-      mips_lo_relocs[SYMBOL_SMALL_DATA] = "%gp_rel(";
+      mips_lo_relocs[SYMBOL_GP_RELATIVE] = "%gp_rel(";
 
       mips_split_p[SYMBOL_GOT_PAGE_OFST] = true;
       if (TARGET_NEWABI)
@@ -6439,7 +6439,7 @@ mips_rewrite_small_data_p (rtx x)
 
   return (TARGET_EXPLICIT_RELOCS
 	  && mips_symbolic_constant_p (x, &symbol_type)
-	  && symbol_type == SYMBOL_SMALL_DATA);
+	  && symbol_type == SYMBOL_GP_RELATIVE);
 }
 
 
@@ -8309,8 +8309,8 @@ mips_use_anchors_for_symbol_p (rtx symbo
 {
   switch (mips_classify_symbol (symbol))
     {
-    case SYMBOL_CONSTANT_POOL:
-    case SYMBOL_SMALL_DATA:
+    case SYMBOL_PC_RELATIVE:
+    case SYMBOL_GP_RELATIVE:
       return false;
 
     default:
Index: gcc/config/mips/predicates.md
===================================================================
--- gcc/config/mips/predicates.md.orig	2007-08-03 17:05:20.000000000 +0100
+++ gcc/config/mips/predicates.md	2007-08-03 17:05:22.000000000 +0100
@@ -101,7 +101,7 @@
 
   switch (symbol_type)
     {
-    case SYMBOL_GENERAL:
+    case SYMBOL_ABSOLUTE:
       /* We can only use direct calls for TARGET_ABSOLUTE_ABICALLS if we
 	 are sure that the target function does not need $25 to be live
 	 on entry.  This is true for any locally-defined function because
@@ -229,11 +229,11 @@
   return mips_symbolic_constant_p (op, &type);
 })
 
-(define_predicate "general_symbolic_operand"
+(define_predicate "absolute_symbolic_operand"
   (match_code "const,symbol_ref,label_ref")
 {
   enum mips_symbol_type type;
-  return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GENERAL;
+  return mips_symbolic_constant_p (op, &type) && type == SYMBOL_ABSOLUTE;
 })
 
 (define_predicate "got_disp_operand"
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md.orig	2007-08-03 17:05:20.000000000 +0100
+++ gcc/config/mips/mips.md	2007-08-03 17:05:22.000000000 +0100
@@ -3094,7 +3094,7 @@
   [(set_attr "type" "store")
    (set_attr "mode" "<MODE>")])
 
-;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
+;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
 ;; The required value is:
 ;;
 ;;	(%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
@@ -3111,7 +3111,7 @@
 ;; to take effect.
 (define_insn_and_split "*lea_high64"
   [(set (match_operand:DI 0 "register_operand" "=d")
-	(high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
+	(high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
   "#"
   "&& epilogue_completed"
@@ -3136,7 +3136,7 @@
 ;;	daddu	op1,op1,op0
 (define_peephole2
   [(set (match_operand:DI 1 "register_operand")
-	(high:DI (match_operand:DI 2 "general_symbolic_operand")))
+	(high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
    (match_scratch:DI 0 "d")]
   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
   [(set (match_dup 1) (high:DI (match_dup 3)))
@@ -3150,7 +3150,7 @@
 })
 
 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
-;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
+;; SYMBOL_ABSOLUTE X will take 6 cycles.  This next pattern allows combine
 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
 ;; used once.  We can then use the sequence:
 ;;
@@ -3164,7 +3164,7 @@
 ;; which takes 4 cycles on most superscalar targets.
 (define_insn_and_split "*lea64"
   [(set (match_operand:DI 0 "register_operand" "=d")
-	(match_operand:DI 1 "general_symbolic_operand" ""))
+	(match_operand:DI 1 "absolute_symbolic_operand" ""))
    (clobber (match_scratch:DI 2 "=&d"))]
   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
   "#"
@@ -4182,7 +4182,7 @@
 				 (match_dup 4)] UNSPEC_LOAD_GOT))]
 {
   operands[2] = pic_offset_table_rtx;
-  operands[3] = mips_unspec_address (operands[0], SYMBOL_GENERAL);
+  operands[3] = mips_unspec_address (operands[0], SYMBOL_ABSOLUTE);
   operands[4] = mips_unspec_address (operands[1], SYMBOL_HALF);
 })
 

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

only message in thread, other threads:[~2007-08-08 15:06 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:06 [committed, 1/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).