OSDN Git Service

* final.c (output_addr_const) [LABEL_REF]: Simplify.
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Nov 2000 06:37:23 +0000 (06:37 +0000)
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Nov 2000 06:37:23 +0000 (06:37 +0000)
[MINUS]: Enclose non-CONST_INTs in parentheses.
[default]: Try OUTPUT_ADDR_CONST_EXTRA.
* tm.texi (OUTPUT_ADDR_CONST_EXTRA): Document it.
* varasm.c (decode_rtx_const) [CONST]: If it's not something
PLUS or MINUS a CONST_INT, use the whole CONST with offset 0
instead of abort()ing.
* sh.c (output_pic_addr_const): Removed.  Fixed all callers.
* sh.h (OUTPUT_ADDR_CONST_EXTRA): New.  Handle the UNSPECs
formerly handled in output_pic_addr_const.
* sh.md (sym_label2reg, symPLT_label2reg): Enclose UNSPEC
operands of MINUS in CONSTs so that decode_rtx_const() will
accept them.

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

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md
gcc/final.c
gcc/tm.texi
gcc/varasm.c

index 3bb689c..7c7411c 100644 (file)
@@ -1,3 +1,19 @@
+Thu Nov 23 04:33:33 2000  Alexandre Oliva  <aoliva@redhat.com>
+
+       * final.c (output_addr_const) [LABEL_REF]: Simplify.
+       [MINUS]: Enclose non-CONST_INTs in parentheses.
+       [default]: Try OUTPUT_ADDR_CONST_EXTRA.
+       * tm.texi (OUTPUT_ADDR_CONST_EXTRA): Document it.
+       * varasm.c (decode_rtx_const) [CONST]: If it's not something
+       PLUS or MINUS a CONST_INT, use the whole CONST with offset 0
+       instead of abort()ing.
+       * sh.c (output_pic_addr_const): Removed.  Fixed all callers.
+       * sh.h (OUTPUT_ADDR_CONST_EXTRA): New.  Handle the UNSPECs
+       formerly handled in output_pic_addr_const.
+       * sh.md (sym_label2reg, symPLT_label2reg): Enclose UNSPEC
+       operands of MINUS in CONSTs so that decode_rtx_const() will
+       accept them.
+
 Thu Nov 23 04:10:30 2000  Alexandre Oliva  <aoliva@redhat.com>
 
        * config/sh/sh.md (mova_const): New pattern.
index e41ae32..7f3fdd3 100644 (file)
@@ -202,7 +202,7 @@ print_operand_address (stream, x)
       break;
 
     default:
-      output_pic_addr_const (stream, x);
+      output_addr_const (stream, x);
       break;
     }
 }
@@ -5334,119 +5334,3 @@ legitimize_pic_address (orig, mode, reg)
     }
   return orig;
 }
-\f
-/* Like output_addr_const(), but recognize PIC unspecs and special
-   expressions.  */
-void
-output_pic_addr_const (file, x)
-     FILE *file;
-     rtx x;
-{
-  char buf[256];
-
-  switch (GET_CODE (x))
-    {
-    case PC:
-      if (flag_pic)
-       putc ('.', file);
-      else
-       abort ();
-      break;
-
-    case SYMBOL_REF:
-      assemble_name (file, XSTR (x, 0));
-      break;
-
-    case LABEL_REF:
-      x = XEXP (x, 0);
-      /* FALLTHRU */
-    case CODE_LABEL:
-      ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
-      assemble_name (asm_out_file, buf);
-      break;
-
-    case CONST:
-      output_pic_addr_const (file, XEXP (x, 0));
-      break;
-
-    case CONST_INT:
-      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
-      break;
-
-    case CONST_DOUBLE:
-      if (GET_MODE (x) == VOIDmode)
-       {
-         /* We can use %d if the number is <32 bits and positive.  */
-         if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
-           fprintf (file, "0x%lx%08lx",
-                    (unsigned long) CONST_DOUBLE_HIGH (x),
-                    (unsigned long) CONST_DOUBLE_LOW (x));
-         else
-           fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
-       }
-      else
-       /* We can't handle floating point constants;
-          PRINT_OPERAND must handle them.  */
-       output_operand_lossage ("floating constant misused");
-      break;
-
-    case PLUS:
-      /* Some assemblers need integer constants to appear first.  */
-      if (GET_CODE (XEXP (x, 0)) == CONST_INT)
-       {
-         output_pic_addr_const (file, XEXP (x, 0));
-         fprintf (file, "+");
-         output_pic_addr_const (file, XEXP (x, 1));
-       }
-      else if (GET_CODE (XEXP (x, 1)) == CONST_INT
-              || GET_CODE (XEXP (x, 0)) == PC)
-       {
-         output_pic_addr_const (file, XEXP (x, 1));
-         fprintf (file, "+");
-         output_pic_addr_const (file, XEXP (x, 0));
-       }
-      else
-       abort ();
-      break;
-
-    case MINUS:
-      output_pic_addr_const (file, XEXP (x, 0));
-      fprintf (file, "-");
-      if (GET_CODE (XEXP (x, 1)) == CONST)
-       {
-         putc ('(', file);
-         output_pic_addr_const (file, XEXP (x, 1));
-         putc (')', file);
-       }
-      else
-       output_pic_addr_const (file, XEXP (x, 1));
-      break;
-
-    case UNSPEC:
-      if ((XVECLEN (x, 0)) > 3)
-       abort ();
-      output_pic_addr_const (file, XVECEXP (x, 0, 0));
-      switch (XINT (x, 1))
-       {
-       case 6:
-         /* GLOBAL_OFFSET_TABLE or local symbols, no suffix.  */
-         break;
-       case 7:
-         fputs ("@GOT", file);
-         break;
-       case 8:
-         fputs ("@GOTOFF", file);
-         break;
-        case 9:
-         fputs ("@PLT", file);
-         break;
-       default:
-         output_operand_lossage ("invalid UNSPEC as operand");
-         break;
-       }
-      break;
-
-    default:
-      output_operand_lossage ("invalid expression as operand");
-    }
-}
index 5dfd213..5476d14 100644 (file)
@@ -2072,12 +2072,12 @@ do { char dstr[30];                                     \
 
 #define ASM_OUTPUT_INT(STREAM, EXP)            \
   (fprintf ((STREAM), "\t.long\t"),            \
-   output_pic_addr_const ((STREAM), (EXP)),    \
+   output_addr_const ((STREAM), (EXP)),        \
    fputc ('\n', (STREAM)))
 
 #define ASM_OUTPUT_SHORT(STREAM, EXP)  \
   (fprintf ((STREAM), "\t.short\t"),   \
-   output_pic_addr_const ((STREAM), (EXP)),    \
+   output_addr_const ((STREAM), (EXP)),        \
    fputc ('\n', (STREAM)))
 
 #define ASM_OUTPUT_CHAR(STREAM, EXP)           \
@@ -2157,6 +2157,40 @@ do { char dstr[30];                                      \
 #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
   ((CHAR) == '.' || (CHAR) == '#' || (CHAR) == '@' || (CHAR) == ','    \
    || (CHAR) == '$')
+
+/* Recognize machine-specific patterns that may appear within
+   constants.  Used for PIC-specific UNSPECs.  */
+#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
+  do                                                                   \
+    if (flag_pic && GET_CODE (X) == UNSPEC && XVECLEN ((X), 0) == 1)   \
+      {                                                                        \
+       switch (XINT ((X), 1))                                          \
+         {                                                             \
+         case UNSPEC_PIC:                                              \
+           /* GLOBAL_OFFSET_TABLE or local symbols, no suffix.  */     \
+           output_addr_const ((STREAM), XVECEXP ((X), 0, 0));          \
+           break;                                                      \
+         case UNSPEC_GOT:                                              \
+           output_addr_const ((STREAM), XVECEXP ((X), 0, 0));          \
+           fputs ("@GOT", (STREAM));                                   \
+           break;                                                      \
+         case UNSPEC_GOTOFF:                                           \
+           output_addr_const ((STREAM), XVECEXP ((X), 0, 0));          \
+           fputs ("@GOTOFF", (STREAM));                                \
+           break;                                                      \
+         case UNSPEC_PLT:                                              \
+           output_addr_const ((STREAM), XVECEXP ((X), 0, 0));          \
+           fputs ("@PLT", (STREAM));                                   \
+           break;                                                      \
+         default:                                                      \
+           goto FAIL;                                                  \
+         }                                                             \
+       break;                                                          \
+      }                                                                        \
+    else                                                               \
+      goto FAIL;                                                       \
+  while (0)
+
 \f
 extern struct rtx_def *sh_compare_op0;
 extern struct rtx_def *sh_compare_op1;
index 34649e0..549c7e7 100644 (file)
 (define_expand "sym_label2reg"
   [(set (match_operand:SI 0 "" "")
        (const (minus:SI
-               (unspec [(match_operand:SI 1 "" "")] UNSPEC_PIC)
+               (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_PIC))
                (const (plus:SI
                        (unspec [(label_ref (match_operand:SI 2 "" ""))]
                                UNSPEC_PIC)
 (define_expand "symPLT_label2reg"
   [(set (match_operand:SI 0 "" "")
        (const (minus:SI
-               (plus:SI (pc)
-                        (unspec [(match_operand:SI 1 "" "")] UNSPEC_PLT))
-               (const
-                (plus:SI
-                 (unspec [(label_ref (match_operand:SI 2 "" ""))] UNSPEC_PIC)
-                 (const_int 2))))))
+               (const (plus:SI
+                       (unspec [(match_operand:SI 1 "" "")] UNSPEC_PLT)
+                       (pc)))
+               (const (plus:SI
+                       (unspec [(label_ref (match_operand:SI 2 "" ""))]
+                               UNSPEC_PIC)
+                       (const_int 2))))))
    (use (match_dup 3))]
   ;; Even though the PIC register is not really used by the call
   ;; sequence in which this is expanded, the PLT code assumes the PIC
index c83f722..46c09ee 100644 (file)
@@ -3677,10 +3677,8 @@ output_addr_const (file, x)
       break;
 
     case LABEL_REF:
-      ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
-      assemble_name (file, buf);
-      break;
-
+      x = XEXP (x, 0);
+      /* Fall through.  */
     case CODE_LABEL:
       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
       assemble_name (file, buf);
@@ -3741,8 +3739,9 @@ output_addr_const (file, x)
 
       output_addr_const (file, XEXP (x, 0));
       fprintf (file, "-");
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
-         && INTVAL (XEXP (x, 1)) < 0)
+      if ((GET_CODE (XEXP (x, 1)) == CONST_INT
+          && INTVAL (XEXP (x, 1)) < 0)
+         || GET_CODE (XEXP (x, 1)) != CONST_INT)
        {
          fprintf (file, "%s", ASM_OPEN_PAREN);
          output_addr_const (file, XEXP (x, 1));
@@ -3758,6 +3757,12 @@ output_addr_const (file, x)
       break;
 
     default:
+#ifdef OUTPUT_ADDR_CONST_EXTRA
+      OUTPUT_ADDR_CONST_EXTRA (file, x, fail);
+      break;
+
+    fail:
+#endif
       output_operand_lossage ("invalid expression as operand");
     }
 }
index 9f443b6..4752d93 100644 (file)
@@ -5500,6 +5500,18 @@ would be identical to repeatedly calling the macro corresponding to
 a size of @code{UNITS_PER_WORD}, once for each word, you need not define
 the macro.
 
+@findex OUTPUT_ADDR_CONST_EXTRA
+@item OUTPUT_ADDR_CONST_EXTRA (@var{stream}, @var{x}, @var{fail})
+A C statement to recognize @var{rtx} patterns that
+@code{output_addr_const} can't deal with, and output assembly code to
+@var{stream} corresponding to the pattern @var{x}.  This may be used to
+allow machine-dependent @code{UNSPEC}s to appear within constants.
+
+If @code{OUTPUT_ADDR_CONST_EXTRA} fails to recognize a pattern, it must
+@code{goto fail}, so that a standard error message is printed.  If it
+prints an error message itself, by calling, for example,
+@code{output_operand_lossage}, it may just complete normally.
+
 @findex ASM_OUTPUT_BYTE
 @item ASM_OUTPUT_BYTE (@var{stream}, @var{value})
 A C statement to output to the stdio stream @var{stream} an assembler
index e9925bf..009b65f 100644 (file)
@@ -3486,22 +3486,21 @@ decode_rtx_const (mode, x, value)
 
     case CONST:
       x = XEXP (x, 0);
-      if (GET_CODE (x) == PLUS)
+      if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
        {
          value->un.addr.base = XEXP (x, 0);
-         if (GET_CODE (XEXP (x, 1)) != CONST_INT)
-           abort ();
          value->un.addr.offset = INTVAL (XEXP (x, 1));
        }
-      else if (GET_CODE (x) == MINUS)
+      else if (GET_CODE (x) == MINUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
        {
          value->un.addr.base = XEXP (x, 0);
-         if (GET_CODE (XEXP (x, 1)) != CONST_INT)
-           abort ();
          value->un.addr.offset = - INTVAL (XEXP (x, 1));
        }
       else
-       abort ();
+       {
+         value->un.addr.base = x;
+         value->un.addr.offset = 0;
+       }
       break;
 
     default: