OSDN Git Service

[pf3gnuchains/gcc-fork.git] / gcc / final.c
index d30e5b2..454ab6c 100644 (file)
@@ -45,11 +45,6 @@ Boston, MA 02111-1307, USA.  */
    FUNCTION_EPILOGUE.  Those instructions never exist as rtl.  */
 
 #include "config.h"
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
 #include "system.h"
 
 #include "tree.h"
@@ -76,8 +71,9 @@ Boston, MA 02111-1307, USA.  */
 #if defined (USG) || !defined (HAVE_STAB_H)
 #include "gstab.h"  /* If doing DBX on sysV, use our own stab.h.  */
 #else
-#include <stab.h>  /* On BSD, use the system's stab.h.  */
-#endif /* not USG */
+#include <stab.h>
+#endif
+
 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
 
 #ifdef XCOFF_DEBUGGING_INFO
@@ -1028,7 +1024,7 @@ shorten_branches (first)
   min_labelno = get_first_label_num ();
   label_align = (struct label_alignment *) xmalloc (
     (max_labelno - min_labelno + 1) * sizeof (struct label_alignment));
-  bzero (label_align,
+  bzero ((char *) label_align,
     (max_labelno - min_labelno + 1) * sizeof (struct label_alignment));
 
   uid_shuid = (int *) xmalloc (max_uid * sizeof *uid_shuid);
@@ -1596,7 +1592,7 @@ final_start_function (first, file, optimize)
       int i;
 
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-       if (!call_used_regs[i] && !call_fixed_regs[i])
+       if (!call_used_regs[i])
          regs_ever_live[i] = 1;
     }
 #endif
@@ -1984,6 +1980,18 @@ final (first, file, optimize, prescan)
         max_uid = INSN_UID (insn);
       if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
         line_note_exists[NOTE_LINE_NUMBER (insn)] = 1;
+#ifdef HAVE_cc0
+      /* If CC tracking across branches is enabled, record the insn which
+        jumps to each branch only reached from one place.  */
+      if (GET_CODE (insn) == JUMP_INSN)
+       {
+         rtx lab = JUMP_LABEL (insn);
+         if (lab && LABEL_NUSES (lab) == 1)
+           {
+             LABEL_REFS (lab) = insn;
+           }
+       }
+#endif
     }
 
   /* Initialize insn_eh_region table if eh is being used. */
@@ -2057,9 +2065,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          && ! exceptions_via_longjmp)
        {
          ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
-#ifndef NEW_EH_MODEL
-         add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
-#endif
+          if (! flag_new_exceptions)
+            add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
 #ifdef ASM_OUTPUT_EH_REGION_BEG
          ASM_OUTPUT_EH_REGION_BEG (file, NOTE_BLOCK_NUMBER (insn));
 #endif
@@ -2070,9 +2077,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          && ! exceptions_via_longjmp)
        {
          ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
-#ifdef NEW_EH_MODEL
-         add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
-#endif
+          if (flag_new_exceptions)
+            add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
 #ifdef ASM_OUTPUT_EH_REGION_END
          ASM_OUTPUT_EH_REGION_END (file, NOTE_BLOCK_NUMBER (insn));
 #endif
@@ -2278,7 +2284,9 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
       if (CODE_LABEL_NUMBER (insn) <= max_labelno)
        {
          int align = LABEL_TO_ALIGNMENT (insn);
+#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
          int max_skip = LABEL_TO_MAX_SKIP (insn);
+#endif
 
          if (align && NEXT_INSN (insn))
 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
@@ -2287,7 +2295,30 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
            ASM_OUTPUT_ALIGN (file, align);
 #endif
        }
+#ifdef HAVE_cc0
       CC_STATUS_INIT;
+      /* If this label is reached from only one place, set the condition
+        codes from the instruction just before the branch.  */
+      if (LABEL_NUSES (insn) == 1)
+       {
+         rtx jump = LABEL_REFS (insn);
+         rtx barrier = prev_nonnote_insn (insn);
+         rtx prev;
+         /* If the LABEL_REFS field of this label has been set to point
+            at a branch, the predecessor of the branch is a regular
+            insn, and that branch is the only way to reach this label,
+            set the condition codes based on the branch and its
+            predecessor.  */
+         if (barrier && GET_CODE (barrier) == BARRIER
+             && jump && GET_CODE (jump) == JUMP_INSN
+             && (prev = prev_nonnote_insn (jump))
+             && GET_CODE (prev) == INSN)
+           {
+             NOTICE_UPDATE_CC (PATTERN (prev), prev);
+             NOTICE_UPDATE_CC (PATTERN (jump), jump);
+           }
+       }
+#endif
       if (prescan > 0)
        break;
       new_block = 1;
@@ -2325,6 +2356,11 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          if (GET_CODE (nextbody) == ADDR_VEC
              || GET_CODE (nextbody) == ADDR_DIFF_VEC)
            {
+#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
+             /* In this case, the case vector is being moved by the
+                target, so don't output the label at all.  Leave that
+                to the back end macros.  */
+#else
              if (! JUMP_TABLES_IN_TEXT_SECTION)
                {
                  readonly_data_section ();
@@ -2343,6 +2379,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 #else
              ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
 #endif
+#endif
              break;
            }
        }
@@ -2396,6 +2433,24 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
                app_on = 0;
              }
 
+#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
+           if (GET_CODE (body) == ADDR_VEC)
+             {
+#ifdef ASM_OUTPUT_ADDR_VEC
+               ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body);
+#else
+               abort();
+#endif
+             }
+           else
+             {
+#ifdef ASM_OUTPUT_ADDR_DIFF_VEC
+               ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body);
+#else
+               abort();
+#endif
+             }
+#else
            vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC);
            for (idx = 0; idx < vlen; idx++)
              {
@@ -2426,6 +2481,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
                                 CODE_LABEL_NUMBER (PREV_INSN (insn)),
                                 insn);
 #endif
+#endif
 
            function_section (current_function_decl);
 
@@ -3020,6 +3076,8 @@ alter_subreg (x)
                   - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));
       PUT_CODE (x, MEM);
       MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);
+      MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (y);
+      MEM_ALIAS_SET (x) = MEM_ALIAS_SET (y);
       XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
     }