OSDN Git Service

Make `solaris' reflect the most recent major release.
[pf3gnuchains/gcc-fork.git] / gcc / rtl.c
index 3c8594b..ac1979f 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -22,12 +22,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <ctype.h>
 #include <stdio.h>
 #include "rtl.h"
+#include "real.h"
 
 #include "obstack.h"
 #define        obstack_chunk_alloc     xmalloc
 #define        obstack_chunk_free      free
-extern int xmalloc ();
-extern void free ();
 
 /* Obstack used for allocating RTL objects.
    Between functions, this is the permanent_obstack.
@@ -37,7 +36,9 @@ extern void free ();
 
 extern struct obstack *rtl_obstack;
 
-extern long ftell();
+#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
+extern long atol();
+#endif
 \f
 /* Indexed by rtx code, gives number of operands for an rtx with that code.
    Does NOT include rtx header data (code and links).
@@ -138,6 +139,8 @@ char *rtx_format[] = {
      "i" an integer
          prints the integer
      "n" like "i", but prints entries from `note_insn_name'
+     "w" an integer of width HOST_BITS_PER_WIDE_INT
+         prints the integer
      "s" a pointer to a string
          prints the string
      "S" like "s", but optional:
@@ -167,11 +170,13 @@ char rtx_class[] = {
 
 /* Names for kinds of NOTEs and REG_NOTEs.  */
 
-char *note_insn_name[] = { "NOTE_INSN_FUNCTION_BEG", "NOTE_INSN_DELETED",
+char *note_insn_name[] = { 0                    , "NOTE_INSN_DELETED",
                           "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
                           "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
                           "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
-                          "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP" };
+                          "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
+                          "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
+                          "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};
 
 char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
                          "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
@@ -229,7 +234,14 @@ rtx_alloc (code)
   ob->next_free += length;
   ob->object_base = ob->next_free;
 
-  * (int *) rt = 0;
+  /* We want to clear everything up to the FLD array.  Normally, this is
+     one int, but we don't want to assume that and it isn't very portable
+     anyway; this is.  */
+
+  length = (sizeof (struct rtx_def) - sizeof (rtunion) - 1) / sizeof (int);
+  for (; length >= 0; length--)
+    ((int *) rt)[length] = 0;
+
   PUT_CODE (rt, code);
 
   return rt;
@@ -260,7 +272,23 @@ copy_rtx (orig)
     case CODE_LABEL:
     case PC:
     case CC0:
+    case SCRATCH:
+      /* SCRATCH must be shared because they represent distinct values. */
       return orig;
+
+    case CONST:
+      /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
+        a LABEL_REF, it isn't sharable.  */
+      if (GET_CODE (XEXP (orig, 0)) == PLUS
+         && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
+         && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
+       return orig;
+      break;
+
+      /* A MEM with a constant address is not sharable.  The problem is that
+        the constant address may need to be reloaded.  If the mem is shared,
+        then reloading one copy of this mem will cause all copies to appear
+        to have been reloaded.  */
     }
 
   copy = rtx_alloc (code);
@@ -282,6 +310,11 @@ copy_rtx (orig)
            XEXP (copy, i) = copy_rtx (XEXP (orig, i));
          break;
 
+       case '0':
+       case 'u':
+         XEXP (copy, i) = XEXP (orig, i);
+         break;
+
        case 'E':
        case 'V':
          XVEC (copy, i) = XVEC (orig, i);
@@ -293,9 +326,21 @@ copy_rtx (orig)
            }
          break;
 
-       default:
+       case 'w':
+         XWINT (copy, i) = XWINT (orig, i);
+         break;
+
+       case 'i':
          XINT (copy, i) = XINT (orig, i);
          break;
+
+       case 's':
+       case 'S':
+         XSTR (copy, i) = XSTR (orig, i);
+         break;
+
+       default:
+         abort ();
        }
     }
   return copy;
@@ -351,6 +396,11 @@ copy_most_rtx (orig, may_share)
            XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
          break;
 
+       case '0':
+       case 'u':
+         XEXP (copy, i) = XEXP (orig, i);
+         break;
+
        case 'E':
        case 'V':
          XVEC (copy, i) = XVEC (orig, i);
@@ -363,9 +413,22 @@ copy_most_rtx (orig, may_share)
            }
          break;
 
-       default:
+       case 'w':
+         XWINT (copy, i) = XWINT (orig, i);
+         break;
+
+       case 'n':
+       case 'i':
          XINT (copy, i) = XINT (orig, i);
          break;
+
+       case 's':
+       case 'S':
+         XSTR (copy, i) = XSTR (orig, i);
+         break;
+
+       default:
+         abort ();
        }
     }
   return copy;
@@ -492,6 +555,7 @@ read_rtx (infile)
   rtx return_rtx;
   register int c;
   int tmp_int;
+  HOST_WIDE_INT tmp_wide;
 
   /* Linked list structure for making RTXs: */
   struct rtx_list
@@ -604,8 +668,7 @@ read_rtx (infile)
            }
          /* get vector length and allocate it */
          XVEC (return_rtx, i) = (list_counter
-                                 ? rtvec_alloc (list_counter)
-                                 : (struct rtvec_def *) NULL);
+                                 ? rtvec_alloc (list_counter) : NULL_RTVEC);
          if (list_counter > 0)
            {
              next_rtx = list_rtx;
@@ -676,6 +739,16 @@ read_rtx (infile)
        }
        break;
 
+      case 'w':
+       read_name (tmp_char, infile);
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+       tmp_wide = atoi (tmp_char);
+#else
+       tmp_wide = atol (tmp_char);
+#endif
+       XWINT (return_rtx, i) = tmp_wide;
+       break;
+
       case 'i':
       case 'n':
        read_name (tmp_char, infile);
@@ -727,9 +800,10 @@ init_rtl ()
       *s++ = 'e';
       *s++ = '0';
       /* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string
-        of as many `i's as we now have elements.  */
-      for (i = 0; i < rtx_length[(int) CONST_DOUBLE]; i++)
-       *s++ = 'i';
+        of as many `w's as we now have elements.  Subtract two from
+        the size to account for the 'e' and the '0'.  */
+      for (i = 2; i < rtx_length[(int) CONST_DOUBLE]; i++)
+       *s++ = 'w';
       *s++ = 0;
     }
 #endif
@@ -751,6 +825,9 @@ init_rtl ()
   for (i = 0; i < (int) MAX_MODE_CLASS; i++)
     min_class_size[i] = 1000;
 
+  byte_mode = VOIDmode;
+  word_mode = VOIDmode;
+
   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
        mode = (enum machine_mode) ((int) mode + 1))
     {
@@ -760,11 +837,13 @@ init_rtl ()
          min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
        }
       if (GET_MODE_CLASS (mode) == MODE_INT
-         && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
+         && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
+         && byte_mode == VOIDmode)
        byte_mode = mode;
 
       if (GET_MODE_CLASS (mode) == MODE_INT
-         && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
+         && GET_MODE_BITSIZE (mode) == BITS_PER_WORD
+         && word_mode == VOIDmode)
        word_mode = mode;
     }
 }