This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Make SH use UNSPECs instead of complicated CONSTs


This patch makes the SH port use UNSPECs instead of things like
(const (minus ...)).  It's part of my ongoing quest to enforce
a grammar for CONSTs.  See:

    http://gcc.gnu.org/ml/gcc-patches/2008-10/msg00339.html

for details.

I expect the idea behind the SH handling was that it was better to
describe things in generic rtl where possible.  The problem is that
ports generally want very specific kinds of constant.  E.g. SH uses:

	(const:SI (minus:SI
		   (const:SI
		    (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
		   (const:SI
		    (minus:SI
		     (const:SI (plus:SI
				(match_operand:SI 2 "" "")
				(const_int 2)))
		     (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))

AIUI, these nested CONSTs are simply there to enforce a particular
bracketing.  The canonical RTL expression would put the -2 addend
in the outermost expression, but we specifically don't want that
here.

AFAIK, this treatment of nested CONSTs isn't documented or guaranteed
anywhere.  It's just something that happens to work.  I think it would
be reasonable for the rtl optimisers to look through these consts and
refactor the expression.

rtl optimisers aren't going to be able to do many useful things
with this, so using UNSPECs seems both simpler and more robust.

The patch adds the following unspecs:

  ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
  ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
  (UNSPEC_EXTRACT_S16	43)
  (UNSPEC_EXTRACT_U16	44)

  ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
  (UNSPEC_SYMOFF	45)

  ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
  (UNSPEC_PCREL_SYMOFF	46)

This scheme also avoids overloading UNSPEC_PIC, which IMO makes
the UNSPEC predicates a little more obvious.

All remaining CONSTs seem to follow the grammar suggested in the
patch above.

I compared the assembly code for gcc.torture, gcc.dg and g++.dg
on sh64-elf with the following options:

  {-O0,-O2} x {-fno-pic,-fpic} x {-m5-compact,-m5-32media,-m5-64media}

There was only one difference:

 gcc.dg/compat/struct-by-value-22_x.c or -O2 -fpic -m5-64media

The before and after code for this test are equivalent, but use
different registers.  The differences start in gcse, which assigns
different hash values to the different constant representations.
It therefore processes GCSEable expressions in a different order after
the patch, and thus creates pseudo registers in a different order.
These registers then get assigned differently.

diffstat says:

 4 files changed, 122 insertions(+), 169 deletions(-)

OK to install?

Richard


gcc/
	* config/sh/sh.h (PREFERRED_RELOAD_CLASS): Test PIC_ADDR_P
	instead of PIC_DIRECT_ADDR_P.
	(SECONDARY_INPUT_RELOAD_CLASS): Likewise.
	(IS_LITERAL_OR_SYMBOLIC_S16_P, IS_LITERAL_OR_SYMBOLIC_U16_P): Delete.
	(IS_NON_EXPLICIT_CONSTANT_P): Don't test PIC_OFFSET_P.
	(PIC_OFFSET_P): Rename to...
	(PCREL_SYMOFF_P): ...this.
	(PIC_DIRECT_ADDR_P): Delete.
	(MOVI_SHORI_BASE_OPERAND_P): Check PCREL_SYMOFF_P instead of
	PIC_OFFSET_P.
	(OUTPUT_ADDR_CONST_EXTRA): Don't require unspecs to have a
	single argument.  Handle UNSPEC_EXTRACT_S16, UNSPEC_EXTRACT_U16,
	UNSPEC_SYMOFF and UNSPEC_PCREL_SYMOFF.
	* config/sh/sh.c (print_operand): Remove CONST handling.
	(unspec_caller_rtx_p): Rewrite to use split_const and check
	the operands of UNSPEC bases.
	(fixup_mova): Replace (unspec [(minus A B)] UNSPEC_PIC)
	with (unspec [A B] UNSPEC_SYMOFF).
	(nonpic_symbol_mentioned_p): Check for UNSPEC_SYMOFF and
	UNSPEC_PCREL_SYMOFF.
	(sh_secondary_reload): Test PIC_ADDR_P instead of PIC_DIRECT_ADDR_P.
	* config/sh/sh.md (UNSPEC_EXTRACT_S16): New unspec.
	(UNSPEC_EXTRACT_U16): Likewise.
	(UNSPEC_SYMOFF): Likewise.
	(UNSPEC_PCREL_SYMOFF): Likewise.
	(movsi_const): Use UNSPEC_EXTRACT_*16s to extract 16-bit portions
	of constants.
	(movsi_const_16bit): Likewise.
	(movdi_const, movdi_const_32bit, movdi_const_16bit): Likewise.
	(GOTaddr2picreg): Replace (unspec [(minus A (minus B pc))] UNSPEC_PIC)
	with (unspec [A B] UNSPEC_PCREL_SYMOFF).
	(sym_label2reg): Replace (minus (const (unspec [A] UNSPEC_PIC)) B)
	with (unspec [A B] UNSPEC_SYMOFF).
	(symPLT_label2reg): Replace (minus A (minus B pc)) with
	 (unspec [A B] PCREL_UNSPEC_SYMOFF).
	* config/sh/constraints.md (Css): Check for an UNSPEC_EXTRACT_S16.
	(Csu): Likewise UNSPEC_EXTRACT_U16.
	(Csy): Test PIC_ADDR_P instead of PIC_DIRECT_ADDR_P.
	(Cpg): Update after changes to IS_NON_EXPLICIT_CONSTANT_P.

Index: gcc/config/sh/sh.h
===================================================================
--- gcc/config/sh/sh.h	2008-10-09 16:54:29.000000000 +0100
+++ gcc/config/sh/sh.h	2008-10-09 16:56:36.000000000 +0100
@@ -1588,7 +1588,7 @@ #define PREFERRED_RELOAD_CLASS(X, CLASS)
   ((CLASS) == NO_REGS && TARGET_SHMEDIA \
    && (GET_CODE (X) == CONST_DOUBLE \
        || GET_CODE (X) == SYMBOL_REF \
-       || PIC_DIRECT_ADDR_P (X)) \
+       || PIC_ADDR_P (X)) \
    ? GENERAL_REGS \
    : (CLASS)) \
 
@@ -1661,7 +1661,7 @@ #define SECONDARY_INPUT_RELOAD_CLASS(CLA
       && TARGET_SHMEDIA && inqhi_operand ((X), (MODE)))			\
    ? GENERAL_REGS							\
    : (TARGET_SHMEDIA && (CLASS) == GENERAL_REGS				\
-      && (GET_CODE (X) == LABEL_REF || PIC_DIRECT_ADDR_P (X)))		\
+      && (GET_CODE (X) == LABEL_REF || PIC_ADDR_P (X)))			\
    ? TARGET_REGS							\
    : SECONDARY_INOUT_RELOAD_CLASS((CLASS),(MODE),(X), NO_REGS))
 #endif
@@ -2288,37 +2288,13 @@ #define IS_PC_RELATIVE_LOAD_ADDR_P(OP)  
        && GET_CODE (XEXP (XEXP ((OP), 0), 0)) == LABEL_REF		\
        && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT))
 
-#define IS_LITERAL_OR_SYMBOLIC_S16_P(OP)				\
-  (GET_CODE ((OP)) == SIGN_EXTEND					\
-   && (GET_MODE ((OP)) == DImode					\
-       || GET_MODE ((OP)) == SImode)					\
-   && GET_CODE (XEXP ((OP), 0)) == TRUNCATE				\
-   && GET_MODE (XEXP ((OP), 0)) == HImode				\
-   && (MOVI_SHORI_BASE_OPERAND_P (XEXP (XEXP ((OP), 0), 0))		\
-       || (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == ASHIFTRT		\
-	   && (MOVI_SHORI_BASE_OPERAND_P				\
-	       (XEXP (XEXP (XEXP ((OP), 0), 0), 0)))			\
-	   && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 1)) == CONST_INT)))
-
-#define IS_LITERAL_OR_SYMBOLIC_U16_P(OP)				\
-  (GET_CODE ((OP)) == ZERO_EXTEND					\
-   && (GET_MODE ((OP)) == DImode					\
-       || GET_MODE ((OP)) == SImode)					\
-   && GET_CODE (XEXP ((OP), 0)) == TRUNCATE				\
-   && GET_MODE (XEXP ((OP), 0)) == HImode				\
-   && (MOVI_SHORI_BASE_OPERAND_P (XEXP (XEXP ((OP), 0), 0))		\
-       || (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == ASHIFTRT		\
-	   && (MOVI_SHORI_BASE_OPERAND_P				\
-	       (XEXP (XEXP (XEXP ((OP), 0), 0), 0)))			\
-	   && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 1)) == CONST_INT)))
-
 #define IS_NON_EXPLICIT_CONSTANT_P(OP)					\
   (CONSTANT_P (OP)							\
    && GET_CODE (OP) != CONST_INT					\
    && GET_CODE (OP) != CONST_DOUBLE					\
    && (!flag_pic							\
        || (LEGITIMATE_PIC_OPERAND_P (OP)				\
-	   && (! PIC_ADDR_P (OP) || PIC_OFFSET_P (OP))			\
+	   && !PIC_ADDR_P (OP)						\
 	   && GET_CODE (OP) != LABEL_REF)))
 
 /* Check whether OP is a datalabel unspec.  */
@@ -2350,13 +2326,10 @@ #define PIC_ADDR_P(OP) \
   (GET_CODE (OP) == CONST && GET_CODE (XEXP ((OP), 0)) == UNSPEC \
    && XINT (XEXP ((OP), 0), 1) == UNSPEC_PIC)
 
-#define PIC_OFFSET_P(OP) \
-  (PIC_ADDR_P (OP) \
-   && GET_CODE (XVECEXP (XEXP ((OP), 0), 0, 0)) == MINUS \
-   && reg_mentioned_p (pc_rtx, XEXP (XVECEXP (XEXP ((OP), 0), 0, 0), 1)))
-
-#define PIC_DIRECT_ADDR_P(OP) \
-  (PIC_ADDR_P (OP) && GET_CODE (XVECEXP (XEXP ((OP), 0), 0, 0)) != MINUS)
+#define PCREL_SYMOFF_P(OP) \
+  (GET_CODE (OP) == CONST \
+   && GET_CODE (XEXP ((OP), 0)) == UNSPEC \
+   && XINT (XEXP ((OP), 0), 1) == UNSPEC_PCREL_SYMOFF)
 
 #define NON_PIC_REFERENCE_P(OP) \
   (GET_CODE (OP) == LABEL_REF || GET_CODE (OP) == SYMBOL_REF \
@@ -2377,7 +2350,7 @@ #define PIC_REFERENCE_P(OP) \
 #define MOVI_SHORI_BASE_OPERAND_P(OP) \
   (flag_pic \
    ? (GOT_ENTRY_P (OP) || GOTPLT_ENTRY_P (OP)  || GOTOFF_P (OP) \
-      || PIC_OFFSET_P (OP)) \
+      || PCREL_SYMOFF_P (OP)) \
    : NON_PIC_REFERENCE_P (OP))
 
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@@ -3106,7 +3079,7 @@ #define PRINT_OPERAND_PUNCT_VALID_P(CHAR
    constants.  Used for PIC-specific UNSPECs.  */
 #define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
   do									\
-    if (GET_CODE (X) == UNSPEC && XVECLEN ((X), 0) == 1)	\
+    if (GET_CODE (X) == UNSPEC)						\
       {									\
 	switch (XINT ((X), 1))						\
 	  {								\
@@ -3155,6 +3128,52 @@ #define OUTPUT_ADDR_CONST_EXTRA(STREAM, 
 	      assemble_name ((STREAM), name);				\
 	    }								\
 	    break;							\
+	  case UNSPEC_EXTRACT_S16:					\
+	  case UNSPEC_EXTRACT_U16:					\
+	    {								\
+	      rtx val, shift;						\
+									\
+	      val = XVECEXP (X, 0, 0);					\
+	      shift = XVECEXP (X, 0, 1);				\
+	      fputc ('(', STREAM);					\
+	      if (shift != const0_rtx)					\
+		fputc ('(', STREAM);					\
+	      if (GET_CODE (val) == CONST				\
+		  || GET_RTX_CLASS (GET_CODE (val)) != RTX_OBJ)		\
+		{							\
+		  fputc ('(', STREAM);					\
+		  output_addr_const (STREAM, val);			\
+		  fputc (')', STREAM);					\
+		}							\
+	      else							\
+		output_addr_const (STREAM, val);			\
+	      if (shift != const0_rtx)					\
+		{							\
+		  fputs (" >> ", STREAM);				\
+		  output_addr_const (STREAM, shift);			\
+		  fputc (')', STREAM);					\
+		}							\
+	      fputs (" & 65535)", STREAM);				\
+	    }								\
+	    break;							\
+	  case UNSPEC_SYMOFF:						\
+	    output_addr_const (STREAM, XVECEXP (X, 0, 0));		\
+	    fputc ('-', STREAM);					\
+	    if (GET_CODE (XVECEXP (X, 0, 1)) == CONST)			\
+	      {								\
+		fputc ('(', STREAM);					\
+		output_addr_const (STREAM, XVECEXP (X, 0, 1));		\
+		fputc (')', STREAM);					\
+	      }								\
+	    else							\
+	      output_addr_const (STREAM, XVECEXP (X, 0, 1));		\
+	    break;							\
+	  case UNSPEC_PCREL_SYMOFF:					\
+	    output_addr_const (STREAM, XVECEXP (X, 0, 0));		\
+	    fputs ("-(", STREAM);					\
+	    output_addr_const (STREAM, XVECEXP (X, 0, 1));		\
+	    fputs ("-.)", STREAM);					\
+	    break;							\
 	  default:							\
 	    goto FAIL;							\
 	  }								\
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	2008-10-09 16:54:29.000000000 +0100
+++ gcc/config/sh/sh.c	2008-10-09 16:56:36.000000000 +0100
@@ -1031,45 +1031,6 @@ print_operand (FILE *stream, rtx x, int 
 	  output_address (XEXP (x, 0));
 	  break;
 
-	case CONST:
-	  if (TARGET_SHMEDIA
-	      && (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
-		  || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
-	      && (GET_MODE (XEXP (x, 0)) == DImode
-		  || GET_MODE (XEXP (x, 0)) == SImode)
-	      && GET_CODE (XEXP (XEXP (x, 0), 0)) == TRUNCATE
-	      && GET_MODE (XEXP (XEXP (x, 0), 0)) == HImode)
-	    {
-	      rtx val = XEXP (XEXP (XEXP (x, 0), 0), 0);
-	      rtx val2 = val;
-	      bool nested_expr = false;
-
-	      fputc ('(', stream);
-	      if (GET_CODE (val) == ASHIFTRT)
-		{
-		  fputc ('(', stream);
-		  val2 = XEXP (val, 0);
-		}
-	      if (GET_CODE (val2) == CONST
-		  || GET_RTX_CLASS (GET_CODE (val2)) != RTX_OBJ)
-		{
-		  fputc ('(', stream);
-		  nested_expr = true;
-		}
-	      output_addr_const (stream, val2);
-	      if (nested_expr)
-		fputc (')', stream);
-	      if (GET_CODE (val) == ASHIFTRT)
-		{
-		  fputs (" >> ", stream);
-		  output_addr_const (stream, XEXP (val, 1));
-		  fputc (')', stream);
-		}
-	      fputs (" & 65535)", stream);
-	      break;
-	    }
-
-	  /* Fall through.  */
 	default:
 	  if (TARGET_SH1)
 	    fputc ('#', stream);
@@ -2191,22 +2152,18 @@ sh_file_start (void)
 static bool
 unspec_caller_rtx_p (rtx pat)
 {
-  switch (GET_CODE (pat))
+  rtx base, offset;
+  int i;
+
+  split_const (pat, &base, &offset);
+  if (GET_CODE (base) == UNSPEC)
     {
-    case CONST:
-      return unspec_caller_rtx_p (XEXP (pat, 0));
-    case PLUS:
-    case MINUS:
-      if (unspec_caller_rtx_p (XEXP (pat, 0)))
+      if (XINT (base, 1) == UNSPEC_CALLER)
 	return true;
-      return unspec_caller_rtx_p (XEXP (pat, 1));
-    case UNSPEC:
-      if (XINT (pat, 1) == UNSPEC_CALLER)
-	return true;
-    default:
-      break;
+      for (i = 0; i < XVECLEN (base, 0); i++)
+	if (unspec_caller_rtx_p (XVECEXP (base, 0, i)))
+	  return true;
     }
-
   return false;
 }
 
@@ -3830,7 +3787,7 @@ fixup_mova (rtx mova)
     {
       rtx worker = mova;
       rtx lab = gen_label_rtx ();
-      rtx wpat, wpat0, wpat1, wsrc, diff;
+      rtx wpat, wpat0, wpat1, wsrc, target, base, diff;
 
       do
 	{
@@ -3849,9 +3806,9 @@ fixup_mova (rtx mova)
 			   XEXP (XVECEXP (wsrc, 0, 2), 0), lab,
 			   XEXP (wpat1, 0)));
       INSN_CODE (worker) = -1;
-      diff = gen_rtx_MINUS (Pmode, XVECEXP (SET_SRC (PATTERN (mova)), 0, 0),
-			    gen_rtx_LABEL_REF (Pmode, lab));
-      diff = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, diff), UNSPEC_PIC);
+      target = XVECEXP (SET_SRC (PATTERN (mova)), 0, 0);
+      base = gen_rtx_LABEL_REF (Pmode, lab);
+      diff = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, target, base), UNSPEC_SYMOFF);
       SET_SRC (PATTERN (mova)) = gen_rtx_CONST (Pmode, diff);
       INSN_CODE (mova) = -1;
     }
@@ -8853,7 +8810,9 @@ nonpic_symbol_mentioned_p (rtx x)
 	  || XINT (x, 1) == UNSPEC_GOTPLT
 	  || XINT (x, 1) == UNSPEC_GOTTPOFF
 	  || XINT (x, 1) == UNSPEC_DTPOFF
-	  || XINT (x, 1) == UNSPEC_PLT))
+	  || XINT (x, 1) == UNSPEC_PLT
+	  || XINT (x, 1) == UNSPEC_SYMOFF
+	  || XINT (x, 1) == UNSPEC_PCREL_SYMOFF))
     return 0;
 
   fmt = GET_RTX_FORMAT (GET_CODE (x));
@@ -11224,7 +11183,7 @@ sh_secondary_reload (bool in_p, rtx x, e
 	  return NO_REGS;
 	}
       if (TARGET_SHMEDIA && rclass == GENERAL_REGS
-          && (GET_CODE (x) == LABEL_REF || PIC_DIRECT_ADDR_P (x)))
+          && (GET_CODE (x) == LABEL_REF || PIC_ADDR_P (x)))
         return TARGET_REGS;
     } /* end of input-only processing.  */
 
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	2008-10-09 16:54:29.000000000 +0100
+++ gcc/config/sh/sh.md	2008-10-09 17:07:09.000000000 +0100
@@ -153,6 +153,17 @@ (define_constants [
   (UNSPEC_SP_TEST	41)
   (UNSPEC_MOVUA		42)
 
+  ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
+  ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
+  (UNSPEC_EXTRACT_S16	43)
+  (UNSPEC_EXTRACT_U16	44)
+
+  ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
+  (UNSPEC_SYMOFF	45)
+
+  ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
+  (UNSPEC_PCREL_SYMOFF	46)
+
   ;; These are used with unspec_volatile.
   (UNSPECV_BLOCKAGE	0)
   (UNSPECV_ALIGN	1)
@@ -5134,16 +5145,12 @@ (define_insn "*movsi_media_nofpu"
 
 (define_expand "movsi_const"
   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
-	(const:SI (sign_extend:SI
-		   (truncate:HI
-		    (ashiftrt:SI
-		     (match_operand:DI 1 "immediate_operand" "s")
-		     (const_int 16))))))
+	(const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
+			      (const_int 16)] UNSPEC_EXTRACT_S16)))
    (set (match_dup 0)
 	(ior:SI (ashift:SI (match_dup 0) (const_int 16))
-		(const:SI
-		  (zero_extend:SI
- 		   (truncate:HI (match_dup 1))))))]
+		(const:SI (unspec:SI [(match_dup 1)
+				      (const_int 0)] UNSPEC_EXTRACT_U16))))]
   "TARGET_SHMEDIA && reload_completed
    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
   "
@@ -5169,9 +5176,8 @@ (define_expand "movsi_const"
 
 (define_expand "movsi_const_16bit"
   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
-	(const:SI (sign_extend:SI
-		   (truncate:HI
-		    (match_operand:DI 1 "immediate_operand" "s")))))]
+	(const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
+			      (const_int 0)] UNSPEC_EXTRACT_S16)))]
   "TARGET_SHMEDIA && flag_pic && reload_completed
    && GET_CODE (operands[1]) == SYMBOL_REF"
   "")
@@ -5588,33 +5594,20 @@ (define_split
 
 (define_expand "movdi_const"
   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
-	(const:DI (sign_extend:DI
-		   (truncate:HI
-		    (ashiftrt:DI
-		     (match_operand:DI 1 "immediate_operand" "s")
-		     (const_int 48))))))
+	(const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
+		  	      (const_int 48)] UNSPEC_EXTRACT_S16)))
    (set (match_dup 0)
 	(ior:DI (ashift:DI (match_dup 0) (const_int 16))
-		(const:DI
-		 (zero_extend:DI
-		  (truncate:HI
-		   (ashiftrt:SI
-		    (match_dup 1)
-		    (const_int 32)))))))
+		(const:DI (unspec:DI [(match_dup 1)
+				      (const_int 32)] UNSPEC_EXTRACT_U16))))
    (set (match_dup 0)
 	(ior:DI (ashift:DI (match_dup 0) (const_int 16))
-		(const:DI
-		 (zero_extend:DI
-		  (truncate:HI
-		   (ashiftrt:SI
-		    (match_dup 1)
-		    (const_int 16)))))))
+		(const:DI (unspec:DI [(match_dup 1)
+				      (const_int 16)] UNSPEC_EXTRACT_U16))))
    (set (match_dup 0)
 	(ior:DI (ashift:DI (match_dup 0) (const_int 16))
-		(const:DI
-		 (zero_extend:DI
-		  (truncate:HI
-		   (match_dup 1))))))]
+		(const:DI (unspec:DI [(match_dup 1)
+				      (const_int 0)] UNSPEC_EXTRACT_U16))))]
   "TARGET_SHMEDIA64 && reload_completed
    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
   "
@@ -5624,17 +5617,12 @@ (define_expand "movdi_const"
 
 (define_expand "movdi_const_32bit"
   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
-	(const:DI (sign_extend:DI
-		   (truncate:HI
-		    (ashiftrt:DI
-		     (match_operand:DI 1 "immediate_operand" "s")
-		     (const_int 16))))))
+	(const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
+			      (const_int 16)] UNSPEC_EXTRACT_S16)))
    (set (match_dup 0)
 	(ior:DI (ashift:DI (match_dup 0) (const_int 16))
-		(const:DI
-		 (zero_extend:DI
-		  (truncate:HI
-		   (match_dup 1))))))]
+		(const:DI (unspec:DI [(match_dup 1)
+				      (const_int 0)] UNSPEC_EXTRACT_U16))))]
   "TARGET_SHMEDIA32 && reload_completed
    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
   "
@@ -5644,9 +5632,8 @@ (define_expand "movdi_const_32bit"
 
 (define_expand "movdi_const_16bit"
   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
-	(const:DI (sign_extend:DI
-		   (truncate:HI
-		    (match_operand:DI 1 "immediate_operand" "s")))))]
+	(const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
+			      (const_int 0)] UNSPEC_EXTRACT_S16)))]
   "TARGET_SHMEDIA && flag_pic && reload_completed
    && GET_CODE (operands[1]) == SYMBOL_REF"
   "")
@@ -8724,16 +8711,9 @@ (define_expand "GOTaddr2picreg"
       rtx insn, equiv;
 
       equiv = operands[1];
-      operands[1] = gen_rtx_MINUS (Pmode,
-				   operands[1],
-				   gen_rtx_CONST
-				   (Pmode,
-				    gen_rtx_MINUS (Pmode,
-						   gen_rtx_CONST (Pmode,
-								  lab),
-						   pc_rtx)));
-      operands[1] = gen_sym2PIC (operands[1]);
-      PUT_MODE (operands[1], Pmode);
+      operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
+				    UNSPEC_PCREL_SYMOFF);
+      operands[1] = gen_rtx_CONST (Pmode, operands[1]);
 
       if (Pmode == SImode)
 	{
@@ -8819,13 +8799,10 @@ (define_expand "call_site"
 
 (define_expand "sym_label2reg"
   [(set (match_operand:SI 0 "" "")
-	(const:SI (minus:SI
-		   (const:SI
-		    (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
-		   (const:SI
-		    (plus:SI
-		     (match_operand:SI 2 "" "")
-		     (const_int 2))))))]
+	(const:SI (unspec:SI [(match_operand:SI 1 "" "")
+			      (const (plus:SI (match_operand:SI 2 "" "")
+					      (const_int 2)))]
+			     UNSPEC_SYMOFF)))]
   "TARGET_SH1" "")
 
 (define_expand "symGOT_load"
@@ -8952,15 +8929,11 @@ (define_expand "symGOTOFF2reg"
 
 (define_expand "symPLT_label2reg"
   [(set (match_operand:SI 0 "" "")
-	(const:SI (minus:SI
-		   (const:SI
-		    (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
-		   (const:SI
-		    (minus:SI
-		     (const:SI (plus:SI
-				(match_operand:SI 2 "" "")
-				(const_int 2)))
-		     (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
+	(const:SI
+	 (unspec:SI
+	  [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
+	   (const:SI (plus:SI (match_operand:SI 2 "" "")
+			      (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
    ;; Even though the PIC register is not really used by the call
    ;; sequence in which this is expanded, the PLT code assumes the PIC
    ;; register is set, so we must not skip its initialization.  Since
Index: gcc/config/sh/constraints.md
===================================================================
--- gcc/config/sh/constraints.md	2008-10-09 16:54:29.000000000 +0100
+++ gcc/config/sh/constraints.md	2008-10-09 16:56:36.000000000 +0100
@@ -27,7 +27,7 @@
 ;;  Csy: label or symbol
 ;;  Cpg: non-explicit constants that can be directly loaded into a general
 ;;       purpose register in PIC code.  like 's' except we don't allow
-;;       PIC_DIRECT_ADDR_P
+;;       PIC_ADDR_P
 ;; IJKLMNOP: CONT_INT constants
 ;;  Ixx: signed xx bit
 ;;  J16: 0xffffffff00000000 | 0x00000000ffffffff
@@ -186,17 +186,19 @@ (define_constraint "Bsc"
 (define_constraint "Css"
   "A signed 16-bit constant, literal or symbolic."
   (and (match_code "const")
-       (match_test "IS_LITERAL_OR_SYMBOLIC_S16_P (XEXP (op, 0))")))
+       (match_test "GET_CODE (XEXP (op, 0)) == UNSPEC")
+       (match_test "XINT (XEXP (op, 0), 1) == UNSPEC_EXTRACT_S16")))
 
 (define_constraint "Csu"
   "An unsigned 16-bit constant, literal or symbolic."
   (and (match_code "const")
-       (match_test "IS_LITERAL_OR_SYMBOLIC_U16_P (XEXP (op, 0))")))
+       (match_test "GET_CODE (XEXP (op, 0)) == UNSPEC")
+       (match_test "XINT (XEXP (op, 0), 1) == UNSPEC_EXTRACT_U16")))
 
 (define_constraint "Csy"
   "A label or a symbol."
   (ior (match_test "NON_PIC_REFERENCE_P (op)")
-       (match_test "PIC_DIRECT_ADDR_P (op)")))
+       (match_test "PIC_ADDR_P (op)")))
 
 (define_constraint "Z"
   "A zero in any shape or form."
@@ -213,7 +215,7 @@ (define_constraint "W"
 (define_constraint "Cpg"
   "A non-explicit constant that can be loaded directly into a general
    purpose register.  This is like 's' except we don't allow
-   PIC_DIRECT_ADDR_P."
+   PIC_ADDR_P."
   (match_test "IS_NON_EXPLICIT_CONSTANT_P (op)"))
 
 (define_constraint "Pso"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]