OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Oct 2008 18:28:25 +0000 (18:28 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Oct 2008 18:28:25 +0000 (18:28 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141046 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/constraints.md
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md

index 85703a2..c3c5908 100644 (file)
@@ -1,3 +1,45 @@
+2008-10-10  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * 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.
+
 2008-10-10  Stepan Kasal  <skasal@redhat.com>
 
        * gcc/doc/invoke.texi (Optimize Options): Fix typo in examples
index 2caa1d5..6b374d1 100644 (file)
@@ -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
 (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."
 (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 533d28c..7c0bdd4 100644 (file)
@@ -1031,45 +1031,6 @@ print_operand (FILE *stream, rtx x, int code)
          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, enum reg_class rclass,
          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 55238af..8b9ec86 100644 (file)
@@ -1588,7 +1588,7 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
   ((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 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
       && 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 @@ struct sh_args {
        && 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 @@ struct sh_args {
   (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 @@ struct sh_args {
 #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))
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@@ -3106,7 +3079,7 @@ struct sh_args {
    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 @@ struct sh_args {
              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 53242aa..68bb197 100644 (file)
   (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 @@ label:
 
 (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 @@ label:
 
 (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 @@ label:
 
 (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 @@ label:
 
 (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 @@ label:
 
 (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 @@ label:
       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 @@ label:
 
 (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 @@ label:
 
 (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