public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed, 7/7] MIPS -mcode-readable support
@ 2007-08-08 15:59 Richard Sandiford
  2007-08-20 18:12 ` David Daney
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Sandiford @ 2007-08-08 15:59 UTC (permalink / raw)
  To: gcc-patches

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

After the rearrangements done by the previous patches, this one is
fairly straight-forward.  The main complication is that MIPS16 has no
"lui" instruction, so we instead need to load the high part using "li"
and then shift it left.  That is, we need a sequence like:

    li $4,%hi(foo)
    sll $4,16

Both of these instructions are extended ones, so (set ... (high ...))
takes the equivalent of 4 unextended instructions.

As usual, we want to split multi-instruction sequences so that they
can be individually scheduled, so we need a way of representing that
unshifted "%hi(foo)".  The patch introduces a SYMBOL_32_HIGH type for
this purpose (to accompany the SYMBOL_64_* types that we already use for
static n64).

[ Note that as things stand, the sll will be further split into two
  unextended slls.  We can revisit them if they're too eager. ]

We also have to make various TARGET_MIPS16 conditions check what
type of code accesses are allowed.  I've introduced some new
convenience macros for this.  In particular, LABEL_REFs are used
for both in-function labels and jump tables, so we can only return
SYMBOL_PC_RELATIVE for labels if -mcode-readable=yes.  This in turn
means that we need an unspec address wrapper around minipool accesses,
in order to force the minipool label to be SYMBOL_PC_RELATIVE for
-mcode-readable=pcrel.

Tested in the same way as the first patch and applied.

Richard


gcc/
2007-08-08  Richard Sandiford  <richard@codesourcery.com>
	    Sandra Loosemore  <sandra@codesourcery.com>
	    Chao-ying Fu  <fu@mips.com>
	    Nigel Stephens  <nigel@mips.com>
	    David Ung  <davidu@mips.com>

	* doc/invoke.texi (-mcode-readable): Document.
	* config/mips/mips.opt (mcode-readable): New option.
	* config/mips/mips-protos.h (SYMBOL_32_HIGH): New symbol type.
	* config/mips/mips.h (mips_code_readable_setting): New enum.
	(mips_code_readable): Declare.
	(TARGET_MIPS16_TEXT_LOADS, TARGET_MIPS16_PCREL_LOADS): New macros.
	(TARGET_MIPS16_SHORT_JUMP_TABLES): New macro.
	(JUMP_TABLES_IN_TEXT_SECTION): Use it.
	(CASE_VECTOR_MODE, CASE_VECTOR_PC_RELATIVE): Likewise.  Remove
	boiler-plate comments.
	(ASM_OUTPUT_ADDR_DIFF_ELT): Use TARGET_MIPS16_SHORT_JUMP_TABLES.
	* config/mips/mips.c (mips_code_readable): New variable.
	(mips_classify_symbol): Only return SYMBOL_PC_RELATIVE for
	MIPS16 labels if TARGET_MIPS16_SHORT_JUMP_TABLES.  Use both the
	context and -mcode-readable setting to restrict the use of
	SYMBOL_PC_RELATIVE for MIPS16 constant pool references.
	Only return TARGET_FORCE_TO_MEM if PC-relative loads are allowed.
	(mips_symbolic_constant_p): Handle SYMBOL_32_HIGH.
	(mips_blocks_for_constant_p): Only return false for
	TARGET_MIPS16_PCREL_LOADS.
	(mips_symbol_insns_1): Treat HIGHs as 2 extended instructions
	for MIPS16.  Handle SYMBOL_32_HIGH.
	(mips_const_insns): Allow HIGHs for MIPS16 too.
	(mips_unspec_address_offset): New function, split out from...
	(mips_unspec_address): ...here.
	(mips_output_move): Handle MIPS16 HIGH moves.  Use "li" to load
	16-bit symbolic constants.  Assert approropiate conditions for
	using the "la" and "dla" macros.
	(mips_handle_option): Handle -mcode-readable=.
	(override_options): Use %hi/%lo relocations for TARGET_MIPS16 too.
	Set up mips_lo_relocs[SYMBOL_32_HIGH].
	(mips_strip_unspec_address): New function, split out from...
	(print_operand_reloc): ...here.
	(print_operand): Pass constants through mips_strip_unspec_address.
	(print_operand_address): Likewise.
	(mips_output_mi_thunk): Remove guard of mips16_lay_out_constants.
	(mips_select_rtx_section): Remove MIPS16 handling.
	(mips16_gp_pseudo_reg): Check currently_expanding_to_rtl.
	(mips16_rewrite_pool_refs): Wrap the labels in an address UNSPEC.
	(mips16_lay_out_constants): Do nothing unless
	TARGET_MIPS16_PCREL_LOADS.
	(mips_avoid_hazards): Remove guard of mips16_lay_out_constants.
	* config/mips/mips.md: Split HIGHs for MIPS16.
	(tablejump): Use TARGET_MIPS16_SHORT_JUMP_TABLES.

gcc/testsuite/
	* gcc.target/mips/code-readable-1.c: New test.
	* gcc.target/mips/code-readable-2.c: Likewise.
	* gcc.target/mips/code-readable-3.c: Likewise.

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	2007-08-08 15:22:01.000000000 +0100
+++ gcc/doc/invoke.texi	2007-08-08 16:46:13.000000000 +0100
@@ -628,6 +628,7 @@ Objective-C and Objective-C++ Dialects}.
 -mlong64  -mlong32  -msym32  -mno-sym32 @gol
 -G@var{num}  -membedded-data  -mno-embedded-data @gol
 -muninit-const-in-rodata  -mno-uninit-const-in-rodata @gol
+-mcode-readable=@var{setting} @gol
 -msplit-addresses  -mno-split-addresses @gol
 -mexplicit-relocs  -mno-explicit-relocs @gol
 -mcheck-zero-division  -mno-check-zero-division @gol
@@ -11779,6 +11780,31 @@ when executing, and thus may be preferre
 Put uninitialized @code{const} variables in the read-only data section.
 This option is only meaningful in conjunction with @option{-membedded-data}.
 
+@item -mcode-readable=@var{setting}
+@opindex mcode-readable
+Specify whether GCC may generate code that reads from executable sections.
+There are three possible settings:
+
+@table @gcctabopt
+@item -mcode-readable=yes
+Instructions may freely access executable sections.  This is the
+default setting.
+
+@item -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.
+
+@item -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.
+@end table
+
 @item -msplit-addresses
 @itemx -mno-split-addresses
 @opindex msplit-addresses
Index: gcc/config/mips/mips.opt
===================================================================
--- gcc/config/mips/mips.opt	2007-08-08 15:22:01.000000000 +0100
+++ gcc/config/mips/mips.opt	2007-08-08 16:49:02.000000000 +0100
@@ -228,6 +228,10 @@ msym32
 Target Report Var(TARGET_SYM32)
 Assume all symbols have 32-bit values
 
+mcode-readable=
+Target RejectNegative Joined
+-mcode-readable=SETTING	Specify when instructions are allowed to access code
+
 mtune=
 Target RejectNegative Joined Var(mips_tune_string)
 -mtune=PROCESSOR	Optimize the output for PROCESSOR
Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h	2007-08-08 16:46:04.000000000 +0100
+++ gcc/config/mips/mips-protos.h	2007-08-08 16:46:13.000000000 +0100
@@ -93,6 +93,9 @@ enum mips_symbol_context {
        UNSPEC wrappers around SYMBOL_TLS, corresponding to the
        thread-local storage relocation operators.
 
+   SYMBOL_32_HIGH
+       For a 32-bit symbolic address X, this is the value of %hi(X).
+
    SYMBOL_64_HIGH
        For a 64-bit symbolic address X, this is the value of
        (%highest(X) << 16) + %higher(X).
@@ -125,6 +128,7 @@ enum mips_symbol_type {
   SYMBOL_DTPREL,
   SYMBOL_GOTTPREL,
   SYMBOL_TPREL,
+  SYMBOL_32_HIGH,
   SYMBOL_64_HIGH,
   SYMBOL_64_MID,
   SYMBOL_64_LOW,
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h	2007-08-08 16:46:04.000000000 +0100
+++ gcc/config/mips/mips.h	2007-08-08 16:46:13.000000000 +0100
@@ -114,6 +114,13 @@ struct mips_cpu_info {
   int isa;
 };
 
+/* Enumerates the setting of the -mcode-readable option.  */
+enum mips_code_readable_setting {
+  CODE_READABLE_NO,
+  CODE_READABLE_PCREL,
+  CODE_READABLE_YES
+};
+
 #ifndef USED_FOR_TARGET
 extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */
 extern const char *current_function_file; /* filename current function is in */
@@ -138,6 +145,7 @@ extern GTY(()) rtx cmp_operands[2];
 extern const struct mips_cpu_info *mips_arch_info;
 extern const struct mips_cpu_info *mips_tune_info;
 extern const struct mips_rtx_cost_data *mips_cost;
+extern enum mips_code_readable_setting mips_code_readable;
 #endif
 
 /* Macros to silence warnings about numbers being signed in traditional
@@ -214,6 +222,16 @@ #define GENERATE_MIPS16E	(TARGET_MIPS16 
 /* Generate mips16e register save/restore sequences.  */
 #define GENERATE_MIPS16E_SAVE_RESTORE (GENERATE_MIPS16E && mips_abi == ABI_32)
 
+/* True if we're generating a form of MIPS16 code in which general
+   text loads are allowed.  */
+#define TARGET_MIPS16_TEXT_LOADS \
+  (TARGET_MIPS16 && mips_code_readable == CODE_READABLE_YES)
+
+/* True if we're generating a form of MIPS16 code in which PC-relative
+   loads are allowed.  */
+#define TARGET_MIPS16_PCREL_LOADS \
+  (TARGET_MIPS16 && mips_code_readable >= CODE_READABLE_PCREL)
+
 /* Generic ISA defines.  */
 #define ISA_MIPS1		    (mips_isa == 1)
 #define ISA_MIPS2		    (mips_isa == 2)
@@ -2270,17 +2288,18 @@ #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FL
 #define SYMBOL_REF_LONG_CALL_P(X)					\
   ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
 
-/* Specify the machine mode that this machine uses
-   for the index in the tablejump instruction.
-   ??? Using HImode in mips16 mode can cause overflow.  */
-#define CASE_VECTOR_MODE \
-  (TARGET_MIPS16 ? HImode : ptr_mode)
-
-/* Define as C expression which evaluates to nonzero if the tablejump
-   instruction expects the table to contain offsets from the address of the
-   table.
-   Do not define this if the table should contain absolute addresses.  */
-#define CASE_VECTOR_PC_RELATIVE (TARGET_MIPS16)
+/* True if we're generating a form of MIPS16 code in which jump tables
+   are stored in the text section and encoded as 16-bit PC-relative
+   offsets.  This is only possible when general text loads are allowed,
+   since the table access itself will be an "lh" instruction.  */
+/* ??? 16-bit offsets can overflow in large functions.  */
+#define TARGET_MIPS16_SHORT_JUMP_TABLES TARGET_MIPS16_TEXT_LOADS
+
+#define JUMP_TABLES_IN_TEXT_SECTION TARGET_MIPS16_SHORT_JUMP_TABLES
+
+#define CASE_VECTOR_MODE (TARGET_MIPS16_SHORT_JUMP_TABLES ? HImode : ptr_mode)
+
+#define CASE_VECTOR_PC_RELATIVE TARGET_MIPS16_SHORT_JUMP_TABLES
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #ifndef DEFAULT_SIGNED_CHAR
@@ -2650,7 +2669,7 @@ #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, 
 
 #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL)		\
 do {									\
-  if (TARGET_MIPS16)							\
+  if (TARGET_MIPS16_SHORT_JUMP_TABLES)					\
     fprintf (STREAM, "\t.half\t%sL%d-%sL%d\n",				\
 	     LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL);	\
   else if (TARGET_GPWORD)						\
@@ -2673,10 +2692,6 @@ #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,
 	     LOCAL_LABEL_PREFIX, VALUE);				\
 } while (0)
 
-/* When generating MIPS16 code, we want the jump table to be in the text
-   section so that we can load its address using a PC-relative addition.  */
-#define JUMP_TABLES_IN_TEXT_SECTION TARGET_MIPS16
-
 /* This is how to output an assembler line
    that says to advance the location counter
    to a multiple of 2**LOG bytes.  */
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2007-08-08 16:46:04.000000000 +0100
+++ gcc/config/mips/mips.c	2007-08-08 16:46:13.000000000 +0100
@@ -616,6 +616,9 @@ int mips_abi = MIPS_ABI_DEFAULT;
 /* Cost information to use.  */
 const struct mips_rtx_cost_data *mips_cost;
 
+/* The -mtext-loads setting.  */
+enum mips_code_readable_setting mips_code_readable = CODE_READABLE_YES;
+
 /* Whether we are generating mips16 hard float code.  In mips16 mode
    we always set TARGET_SOFT_FLOAT; this variable is nonzero if
    -msoft-float was not specified by the user, which means that we
@@ -1444,7 +1447,10 @@ mips_classify_symbol (rtx x, enum mips_s
 
   if (GET_CODE (x) == LABEL_REF)
     {
-      if (TARGET_MIPS16)
+      /* LABEL_REFs are used for jump tables as well as text labels.
+	 Only return SYMBOL_PC_RELATIVE if we know the label is in
+	 the text section.  */
+      if (TARGET_MIPS16_SHORT_JUMP_TABLES)
 	return SYMBOL_PC_RELATIVE;
       if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
 	return SYMBOL_GOT_PAGE_OFST;
@@ -1458,7 +1464,10 @@ mips_classify_symbol (rtx x, enum mips_s
 
   if (CONSTANT_POOL_ADDRESS_P (x))
     {
-      if (TARGET_MIPS16)
+      if (TARGET_MIPS16_TEXT_LOADS)
+	return SYMBOL_PC_RELATIVE;
+
+      if (TARGET_MIPS16_PCREL_LOADS && context == SYMBOL_CONTEXT_MEM)
 	return SYMBOL_PC_RELATIVE;
 
       if (!TARGET_EMBEDDED_DATA
@@ -1502,7 +1511,7 @@ mips_classify_symbol (rtx x, enum mips_s
       return SYMBOL_GOT_PAGE_OFST;
     }
 
-  if (TARGET_MIPS16 && context != SYMBOL_CONTEXT_CALL)
+  if (TARGET_MIPS16_PCREL_LOADS && context != SYMBOL_CONTEXT_CALL)
     return SYMBOL_FORCE_TO_MEM;
   return SYMBOL_ABSOLUTE;
 }
@@ -1560,6 +1569,7 @@ mips_symbolic_constant_p (rtx x, enum mi
     {
     case SYMBOL_ABSOLUTE:
     case SYMBOL_FORCE_TO_MEM:
+    case SYMBOL_32_HIGH:
     case SYMBOL_64_HIGH:
     case SYMBOL_64_MID:
     case SYMBOL_64_LOW:
@@ -1774,14 +1784,14 @@ mips_cannot_force_const_mem (rtx x)
   return false;
 }
 
-/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P.  MIPS16 uses per-function
-   constant pools, but normal-mode code doesn't need to.  */
+/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P.  We can't use blocks for
+   constants when we're using a per-function constant pool.  */
 
 static bool
 mips_use_blocks_for_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED,
 				rtx x ATTRIBUTE_UNUSED)
 {
-  return !TARGET_MIPS16;
+  return !TARGET_MIPS16_PCREL_LOADS;
 }
 \f
 /* Like mips_symbol_insns, but treat extended MIPS16 instructions as a
@@ -1805,8 +1815,9 @@ mips_symbol_insns_1 (enum mips_symbol_ty
 	     dsll    $at,$at,16
 
 	 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;
+	 symbols we just need a preparatory lui for normal mode and
+	 a preparatory "li; sll" for MIPS16.  */
+      return ABI_HAS_64BIT_SYMBOLS ? 6 : TARGET_MIPS16 ? 3 : 2;
 
     case SYMBOL_GP_RELATIVE:
       /* Treat GP-relative accesses as taking a single instruction on
@@ -1863,6 +1874,7 @@ mips_symbol_insns_1 (enum mips_symbol_ty
     case SYMBOL_GOTOFF_DISP:
     case SYMBOL_GOTOFF_CALL:
     case SYMBOL_GOTOFF_LOADGP:
+    case SYMBOL_32_HIGH:
     case SYMBOL_64_HIGH:
     case SYMBOL_64_MID:
     case SYMBOL_64_LOW:
@@ -1875,7 +1887,7 @@ mips_symbol_insns_1 (enum mips_symbol_ty
       /* 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;
+      return !mips_split_p[type] ? 1 : TARGET_MIPS16 ? 3 : 2;
 
     case SYMBOL_TLS:
       /* We don't treat a bare TLS symbol as a constant.  */
@@ -1989,13 +2001,14 @@ mips_const_insns (rtx x)
   switch (GET_CODE (x))
     {
     case HIGH:
-      if (TARGET_MIPS16
-	  || !mips_symbolic_constant_p (XEXP (x, 0), SYMBOL_CONTEXT_LEA,
-					&symbol_type)
+      if (!mips_symbolic_constant_p (XEXP (x, 0), SYMBOL_CONTEXT_LEA,
+				     &symbol_type)
 	  || !mips_split_p[symbol_type])
 	return 0;
 
-      return 1;
+      /* This is simply an lui for normal mode.  It is an extended
+	 "li" followed by an extended "sll" for MIPS16.  */
+      return TARGET_MIPS16 ? 4 : 1;
 
     case CONST_INT:
       if (TARGET_MIPS16)
@@ -2173,6 +2186,20 @@ mips_split_symbol (rtx temp, rtx addr, e
 }
 
 
+/* Wrap symbol or label BASE in an unspec address of type SYMBOL_TYPE
+   and add CONST_INT OFFSET to the result.  */
+
+static rtx
+mips_unspec_address_offset (rtx base, rtx offset,
+			    enum mips_symbol_type symbol_type)
+{
+  base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
+			 UNSPEC_ADDRESS_FIRST + symbol_type);
+  if (offset != const0_rtx)
+    base = gen_rtx_PLUS (Pmode, base, offset);
+  return gen_rtx_CONST (Pmode, base);
+}
+
 /* Return an UNSPEC address with underlying address ADDRESS and symbol
    type SYMBOL_TYPE.  */
 
@@ -2182,11 +2209,7 @@ mips_unspec_address (rtx address, enum m
   rtx base, offset;
 
   split_const (address, &base, &offset);
-  base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
-			 UNSPEC_ADDRESS_FIRST + symbol_type);
-  if (offset != const0_rtx)
-    base = gen_rtx_PLUS (Pmode, base, offset);
-  return gen_rtx_CONST (Pmode, base);
+  return mips_unspec_address_offset (base, offset, symbol_type);
 }
 
 
@@ -3130,6 +3153,7 @@ mips_split_64bit_move (rtx dest, rtx src
 mips_output_move (rtx dest, rtx src)
 {
   enum rtx_code dest_code, src_code;
+  enum mips_symbol_type symbol_type;
   bool dbl_p;
 
   dest_code = GET_CODE (dest);
@@ -3217,13 +3241,27 @@ mips_output_move (rtx dest, rtx src)
 	}
 
       if (src_code == HIGH)
-	return "lui\t%0,%h1";
+	return TARGET_MIPS16 ? "#" : "lui\t%0,%h1";
 
       if (CONST_GP_P (src))
 	return "move\t%0,%1";
 
+      if (mips_symbolic_constant_p (src, SYMBOL_CONTEXT_LEA, &symbol_type)
+	  && mips_lo_relocs[symbol_type] != 0)
+	{
+	  /* A signed 16-bit constant formed by applying a relocation
+	     operator to a symbolic address.  */
+	  gcc_assert (!mips_split_p[symbol_type]);
+	  return "li\t%0,%R1";
+	}
+
       if (symbolic_operand (src, VOIDmode))
-	return (dbl_p ? "dla\t%0,%1" : "la\t%0,%1");
+	{
+	  gcc_assert (TARGET_MIPS16
+		      ? TARGET_MIPS16_TEXT_LOADS
+		      : !TARGET_EXPLICIT_RELOCS);
+	  return (dbl_p ? "dla\t%0,%1" : "la\t%0,%1");
+	}
     }
   if (src_code == REG && FP_REG_P (REGNO (src)))
     {
@@ -5007,6 +5045,17 @@ mips_handle_option (size_t code, const c
       mips_cache_flush_func = NULL;
       return true;
 
+    case OPT_mcode_readable_:
+      if (strcmp (arg, "yes") == 0)
+	mips_code_readable = CODE_READABLE_YES;
+      else if (strcmp (arg, "pcrel") == 0)
+	mips_code_readable = CODE_READABLE_PCREL;
+      else if (strcmp (arg, "no") == 0)
+	mips_code_readable = CODE_READABLE_NO;
+      else
+	return false;
+      return true;
+
     default:
       return true;
     }
@@ -5456,11 +5505,13 @@ override_options (void)
     }
   else
     {
-      if (TARGET_EXPLICIT_RELOCS || mips_split_addresses)
+      if (TARGET_EXPLICIT_RELOCS || mips_split_addresses || TARGET_MIPS16)
 	{
 	  mips_split_p[SYMBOL_ABSOLUTE] = true;
 	  mips_hi_relocs[SYMBOL_ABSOLUTE] = "%hi(";
 	  mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
+
+	  mips_lo_relocs[SYMBOL_32_HIGH] = "%hi(";
 	}
     }
 
@@ -5718,6 +5769,20 @@ mips_debugger_offset (rtx addr, HOST_WID
   return offset;
 }
 \f
+/* If OP is an UNSPEC address, return the address to which it refers,
+   otherwise return OP itself.  */
+
+static rtx
+mips_strip_unspec_address (rtx op)
+{
+  rtx base, offset;
+
+  split_const (op, &base, &offset);
+  if (UNSPEC_ADDRESS_P (base))
+    op = plus_constant (UNSPEC_ADDRESS (base), INTVAL (offset));
+  return op;
+}
+
 /* Implement the PRINT_OPERAND macro.  The MIPS-specific operand codes are:
 
    'X'  OP is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
@@ -6055,7 +6120,7 @@ print_operand (FILE *file, rtx op, int l
     fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
 
   else
-    output_addr_const (file, op);
+    output_addr_const (file, mips_strip_unspec_address (op));
 }
 
 
@@ -6068,19 +6133,13 @@ print_operand_reloc (FILE *file, rtx op,
 {
   enum mips_symbol_type symbol_type;
   const char *p;
-  rtx base, offset;
 
   if (!mips_symbolic_constant_p (op, context, &symbol_type)
       || relocs[symbol_type] == 0)
     fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
 
-  /* If OP uses an UNSPEC address, we want to print the inner symbol.  */
-  split_const (op, &base, &offset);
-  if (UNSPEC_ADDRESS_P (base))
-    op = plus_constant (UNSPEC_ADDRESS (base), INTVAL (offset));
-
   fputs (relocs[symbol_type], file);
-  output_addr_const (file, op);
+  output_addr_const (file, mips_strip_unspec_address (op));
   for (p = relocs[symbol_type]; *p != 0; p++)
     if (*p == '(')
       fputc (')', file);
@@ -6113,7 +6172,7 @@ print_operand_address (FILE *file, rtx x
 	return;
 
       case ADDRESS_SYMBOLIC:
-	output_addr_const (file, x);
+	output_addr_const (file, mips_strip_unspec_address (x));
 	return;
       }
   gcc_unreachable ();
@@ -8192,8 +8251,7 @@ mips_output_mi_thunk (FILE *file, tree t
   insn = get_insns ();
   insn_locators_alloc ();
   split_all_insns_noflow ();
-  if (TARGET_MIPS16)
-    mips16_lay_out_constants ();
+  mips16_lay_out_constants ();
   shorten_branches (insn);
   final_start_function (insn, file, 1);
   final (insn, file, 1);
@@ -8232,14 +8290,7 @@ symbolic_expression_p (rtx x)
 mips_select_rtx_section (enum machine_mode mode, rtx x,
 			 unsigned HOST_WIDE_INT align)
 {
-  if (TARGET_MIPS16)
-    {
-      /* In mips16 mode, the constant table always goes in the same section
-         as the function, so that constants can be loaded using PC relative
-         addressing.  */
-      return function_section (current_function_decl);
-    }
-  else if (TARGET_EMBEDDED_DATA)
+  if (TARGET_EMBEDDED_DATA)
     {
       /* For embedded applications, always put constants in read-only data,
 	 in order to reduce RAM usage.  */
@@ -8827,7 +8878,7 @@ mips16_gp_pseudo_reg (void)
   /* Don't initialize the pseudo register if we are being called from
      the tree optimizers' cost-calculation routines.  */
   if (!cfun->machine->initialized_mips16_gp_pseudo_p
-      && current_ir_type () != IR_GIMPLE)
+      && (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl))
     {
       rtx insn, scan;
 
@@ -9546,11 +9597,23 @@ mips16_insn_length (rtx insn)
 mips16_rewrite_pool_refs (rtx *x, void *data)
 {
   struct mips16_constant_pool *pool = data;
-  if (GET_CODE (*x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (*x))
-    *x = gen_rtx_LABEL_REF (Pmode, add_constant (pool,
-						 get_pool_constant (*x),
-						 get_pool_mode (*x)));
-  return 0;
+  rtx base, offset, label;
+
+  if (MEM_P (*x))
+    x = &XEXP (*x, 0);
+  else if (!TARGET_MIPS16_TEXT_LOADS)
+    return 0;
+
+  split_const (*x, &base, &offset);
+  if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
+    {
+      label = add_constant (pool, get_pool_constant (base),
+			    get_pool_mode (base));
+      base = gen_rtx_LABEL_REF (Pmode, label);
+      *x = mips_unspec_address_offset (base, offset, SYMBOL_PC_RELATIVE);
+      return -1;
+    }
+  return GET_CODE (*x) == CONST ? -1 : 0;
 }
 
 /* Build MIPS16 constant pools.  */
@@ -9561,6 +9624,9 @@ mips16_lay_out_constants (void)
   struct mips16_constant_pool pool;
   rtx insn, barrier;
 
+  if (!TARGET_MIPS16_PCREL_LOADS)
+    return;
+
   barrier = 0;
   memset (&pool, 0, sizeof (pool));
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
@@ -10117,9 +10183,8 @@ mips_avoid_hazards (void)
 static void
 mips_reorg (void)
 {
-  if (TARGET_MIPS16)
-    mips16_lay_out_constants ();
-  else if (TARGET_EXPLICIT_RELOCS)
+  mips16_lay_out_constants ();
+  if (TARGET_EXPLICIT_RELOCS)
     {
       if (mips_flag_delayed_branch)
 	dbr_schedule (get_insns ());
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md	2007-08-08 16:46:04.000000000 +0100
+++ gcc/config/mips/mips.md	2007-08-08 16:46:13.000000000 +0100
@@ -3181,6 +3181,22 @@ (define_insn_and_split "*lea64"
 }
   [(set_attr "length" "24")])
 
+;; Split HIGHs into:
+;;
+;;	li op0,%hi(sym)
+;;	sll op0,16
+;;
+;; on MIPS16 targets.
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "=d")
+	(high:SI (match_operand:SI 1 "absolute_symbolic_operand" "")))]
+  "TARGET_MIPS16 && reload_completed"
+  [(set (match_dup 0) (match_dup 2))
+   (set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16)))]
+{
+  operands[2] = mips_unspec_address (operands[1], SYMBOL_32_HIGH);
+})
+
 ;; Insns to fetch a symbol from a big GOT.
 
 (define_insn_and_split "*xgot_hi<mode>"
@@ -5050,7 +5066,7 @@ (define_expand "tablejump"
    (use (label_ref (match_operand 1 "")))]
   ""
 {
-  if (TARGET_MIPS16)
+  if (TARGET_MIPS16_SHORT_JUMP_TABLES)
     operands[0] = expand_binop (Pmode, add_optab,
 				convert_to_mode (Pmode, operands[0], false),
 				gen_rtx_LABEL_REF (Pmode, operands[1]),
Index: gcc/testsuite/gcc.target/mips/code-readable-1.c
===================================================================
--- /dev/null	2007-08-08 08:10:29.588099250 +0100
+++ gcc/testsuite/gcc.target/mips/code-readable-1.c	2007-08-08 16:46:13.000000000 +0100
@@ -0,0 +1,34 @@
+/* { dg-mips-options "-mips16 -mcode-readable=yes -mgp32" } */
+
+int
+foo (int i)
+{
+  switch (i)
+    {
+    case 1: return 40;
+    case 2: return 11;
+    case 3: return 29;
+    case 4: return 10;
+    case 5: return 12;
+    case 6: return 35;
+    case 7: return 23;
+    default: return 0;
+    }
+}
+
+extern int k[];
+
+int *
+bar (void)
+{
+  return k;
+}
+
+/* { dg-final { scan-assembler "\tla\t" } } */
+/* { dg-final { scan-assembler "\t\.half\t" } } */
+/* { dg-final { scan-assembler-not "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler-not "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler "\t\.word\tk\n" } } */
+/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */
Index: gcc/testsuite/gcc.target/mips/code-readable-2.c
===================================================================
--- /dev/null	2007-08-08 08:10:29.588099250 +0100
+++ gcc/testsuite/gcc.target/mips/code-readable-2.c	2007-08-08 16:46:13.000000000 +0100
@@ -0,0 +1,34 @@
+/* { dg-mips-options "-mips16 -mcode-readable=pcrel -mgp32" } */
+
+int
+foo (int i)
+{
+  switch (i)
+    {
+    case 1: return 40;
+    case 2: return 11;
+    case 3: return 29;
+    case 4: return 10;
+    case 5: return 12;
+    case 6: return 35;
+    case 7: return 23;
+    default: return 0;
+    }
+}
+
+extern int k[];
+
+int *
+bar (void)
+{
+  return k;
+}
+
+/* { dg-final { scan-assembler-not "\tla\t" } } */
+/* { dg-final { scan-assembler-not "\t\.half\t" } } */
+/* { dg-final { scan-assembler "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler "\t\.word\tk\n" } } */
+/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */
Index: gcc/testsuite/gcc.target/mips/code-readable-3.c
===================================================================
--- /dev/null	2007-08-08 08:10:29.588099250 +0100
+++ gcc/testsuite/gcc.target/mips/code-readable-3.c	2007-08-08 16:46:13.000000000 +0100
@@ -0,0 +1,34 @@
+/* { dg-mips-options "-mips16 -mcode-readable=no -mgp32" } */
+
+int
+foo (int i)
+{
+  switch (i)
+    {
+    case 1: return 40;
+    case 2: return 11;
+    case 3: return 29;
+    case 4: return 10;
+    case 5: return 12;
+    case 6: return 35;
+    case 7: return 23;
+    default: return 0;
+    }
+}
+
+extern int k[];
+
+int *
+bar (void)
+{
+  return k;
+}
+
+/* { dg-final { scan-assembler-not "\tla\t" } } */
+/* { dg-final { scan-assembler-not "\t\.half\t" } } */
+/* { dg-final { scan-assembler "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler-not "\t\.word\tk\n" } } */
+/* { dg-final { scan-assembler "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler "%lo\\(k\\)" } } */

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [committed, 7/7] MIPS -mcode-readable support
  2007-08-08 15:59 [committed, 7/7] MIPS -mcode-readable support Richard Sandiford
@ 2007-08-20 18:12 ` David Daney
  2007-08-20 18:25   ` Richard Sandiford
  0 siblings, 1 reply; 3+ messages in thread
From: David Daney @ 2007-08-20 18:12 UTC (permalink / raw)
  To: gcc-patches, richard

[-- Attachment #1: Type: text/plain, Size: 397 bytes --]

Richard Sandiford wrote:

> gcc/testsuite/
> 	* gcc.target/mips/code-readable-1.c: New test.
> 	* gcc.target/mips/code-readable-2.c: Likewise.
> 	* gcc.target/mips/code-readable-3.c: Likewise.

See:
http://gcc.gnu.org/ml/gcc-testresults/2007-08/msg00661.html

Similar results I think on mips64-linux cross compiler.

It is probably not expected that I would get the attached errors.

David Daney


[-- Attachment #2: code-readable.errors --]
[-- Type: text/plain, Size: 5435 bytes --]

Executing on host: /home/build/gcc-build/gcc/xgcc -B/home/build/gcc-build/gcc/ /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c   -mips16 -mcode-readable=yes -mgp32 -fno-show-column -S  -o code-readable-1.s    (timeout = 300)
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c: In function 'bar':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: error: insn does not satisfy its constraints:
(insn 21 2 5 /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:24 (set (reg:SI 2 $2)
        (symbol_ref:SI ("k") [flags 0x40] <var_decl 0x2ae04380 k>)) 212 {*movsi_mips16} (nil))
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: internal compiler error: in extract_constrain_insn_cached, at recog.c:1907
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
compiler exited with status 1
output is:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c: In function 'bar':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: error: insn does not satisfy its constraints:
(insn 21 2 5 /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:24 (set (reg:SI 2 $2)
        (symbol_ref:SI ("k") [flags 0x40] <var_decl 0x2ae04380 k>)) 212 {*movsi_mips16} (nil))
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: internal compiler error: in extract_constrain_insn_cached, at recog.c:1907
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

FAIL: gcc.target/mips/code-readable-1.c (internal compiler error)
FAIL: gcc.target/mips/code-readable-1.c (test for excess errors)
Excess errors:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: error: insn does not satisfy its constraints:
(insn 21 2 5 /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:24 (set (reg:SI 2 $2)
        (symbol_ref:SI ("k") [flags 0x40] <var_decl 0x2ae04380 k>)) 212 {*movsi_mips16} (nil))
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: internal compiler error: in extract_constrain_insn_cached, at recog.c:1907

ERROR: gcc.target/mips/code-readable-1.c: error executing dg-final: couldn't open "code-readable-1.s": no such file or directory
UNRESOLVED: gcc.target/mips/code-readable-1.c: error executing dg-final: couldn't open "code-readable-1.s": no such file or directory
Executing on host: /home/build/gcc-build/gcc/xgcc -B/home/build/gcc-build/gcc/ /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c   -mips16 -mcode-readable=pcrel -mgp32 -fno-show-column -S  -o code-readable-2.s    (timeout = 300)
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c: In function 'foo':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
compiler exited with status 1
output is:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c: In function 'foo':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

FAIL: gcc.target/mips/code-readable-2.c (internal compiler error)
FAIL: gcc.target/mips/code-readable-2.c (test for excess errors)
Excess errors:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282

ERROR: gcc.target/mips/code-readable-2.c: error executing dg-final: couldn't open "code-readable-2.s": no such file or directory
UNRESOLVED: gcc.target/mips/code-readable-2.c: error executing dg-final: couldn't open "code-readable-2.s": no such file or directory
Executing on host: /home/build/gcc-build/gcc/xgcc -B/home/build/gcc-build/gcc/ /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c   -mips16 -mcode-readable=no -mgp32 -fno-show-column -S  -o code-readable-3.s    (timeout = 300)
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c: In function 'foo':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
compiler exited with status 1
output is:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c: In function 'foo':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

FAIL: gcc.target/mips/code-readable-3.c (internal compiler error)
FAIL: gcc.target/mips/code-readable-3.c (test for excess errors)
Excess errors:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282

ERROR: gcc.target/mips/code-readable-3.c: error executing dg-final: couldn't open "code-readable-3.s": no such file or directory

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [committed, 7/7] MIPS -mcode-readable support
  2007-08-20 18:12 ` David Daney
@ 2007-08-20 18:25   ` Richard Sandiford
  0 siblings, 0 replies; 3+ messages in thread
From: Richard Sandiford @ 2007-08-20 18:25 UTC (permalink / raw)
  To: David Daney; +Cc: gcc-patches

David Daney <ddaney@avtrex.com> writes:
> Richard Sandiford wrote:
>
>> gcc/testsuite/
>> 	* gcc.target/mips/code-readable-1.c: New test.
>> 	* gcc.target/mips/code-readable-2.c: Likewise.
>> 	* gcc.target/mips/code-readable-3.c: Likewise.
>
> See:
> http://gcc.gnu.org/ml/gcc-testresults/2007-08/msg00661.html
>
> Similar results I think on mips64-linux cross compiler.
>
> It is probably not expected that I would get the attached errors.

Actually, it is kind-of expected.  This is just because we're trying to
use MIPS16 abicalls, which isn't a supported combination.  I've never been
brave enough to make it a hard error, because -- as the gcc.target/mips
directory shows -- there are cases where a careful user could get by with
-mips16 -mabicalls, and I'd probably be accused of breaking something that
previously worked.  These particular tests are not such cases.

For the time being, can you try adding -mno-abicalls to the
dg-mips-options for these tests?

Richard

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-08-20 18:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-08 15:59 [committed, 7/7] MIPS -mcode-readable support Richard Sandiford
2007-08-20 18:12 ` David Daney
2007-08-20 18:25   ` 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).