OSDN Git Service

Delete !REGISTER_CONSTRAINTS code
[pf3gnuchains/gcc-fork.git] / gcc / final.c
index 58361ab..5ef12ef 100644 (file)
@@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include "tree.h"
 #include "rtl.h"
+#include "tm_p.h"
 #include "regs.h"
 #include "insn-config.h"
 #include "insn-flags.h"
@@ -284,7 +285,9 @@ struct bb_str {
   int length;                  /* string length */
 };
 
+#ifdef HAVE_peephole
 extern rtx peephole            PROTO((rtx));
+#endif
 
 static struct bb_str *sbb_head = 0;            /* Head of string list.  */
 static struct bb_str **sbb_tail        = &sbb_head;    /* Ptr to store next bb str */
@@ -423,9 +426,11 @@ end_final (filename)
       if (write_symbols != NO_DEBUG && profile_block_flag)
        {
          ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 5);
-         assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes, 1);
+         assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name),
+                           pointer_bytes, 1);
          ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 6);
-         assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes, 1);
+         assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name),
+                           pointer_bytes, 1);
        }
       else
        {
@@ -795,27 +800,27 @@ get_attr_length (insn)
    address mod X to one mod Y, which is Y - X.  */
 
 #ifndef LABEL_ALIGN
-#define LABEL_ALIGN(LABEL) 0
+#define LABEL_ALIGN(LABEL) align_labels_log
 #endif
 
 #ifndef LABEL_ALIGN_MAX_SKIP
-#define LABEL_ALIGN_MAX_SKIP 0
+#define LABEL_ALIGN_MAX_SKIP (align_labels-1)
 #endif
 
 #ifndef LOOP_ALIGN
-#define LOOP_ALIGN(LABEL) 0
+#define LOOP_ALIGN(LABEL) align_loops_log
 #endif
 
 #ifndef LOOP_ALIGN_MAX_SKIP
-#define LOOP_ALIGN_MAX_SKIP 0
+#define LOOP_ALIGN_MAX_SKIP (align_loops-1)
 #endif
 
 #ifndef LABEL_ALIGN_AFTER_BARRIER
-#define LABEL_ALIGN_AFTER_BARRIER(LABEL) 0
+#define LABEL_ALIGN_AFTER_BARRIER(LABEL) align_jumps_log
 #endif
 
 #ifndef LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
-#define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP 0
+#define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP (align_jumps-1)
 #endif
 
 #ifndef ADDR_VEC_ALIGN
@@ -1023,10 +1028,8 @@ shorten_branches (first)
 
   max_labelno = max_label_num ();
   min_labelno = get_first_label_num ();
-  label_align = (struct label_alignment *) xmalloc (
-    (max_labelno - min_labelno + 1) * sizeof (struct label_alignment));
-  bzero ((char *) label_align,
-    (max_labelno - min_labelno + 1) * sizeof (struct label_alignment));
+  label_align = (struct label_alignment *)
+    xcalloc ((max_labelno - min_labelno + 1), sizeof (struct label_alignment));
 
   uid_shuid = (int *) xmalloc (max_uid * sizeof *uid_shuid);
 
@@ -1146,24 +1149,19 @@ shorten_branches (first)
 
   /* Allocate the rest of the arrays.  */
   insn_lengths = (short *) xmalloc (max_uid * sizeof (short));
-  insn_addresses = (int *) xmalloc (max_uid * sizeof (int));
   insn_lengths_max_uid = max_uid;
   /* Syntax errors can lead to labels being outside of the main insn stream.
      Initialize insn_addresses, so that we get reproducible results.  */
-  bzero ((char *)insn_addresses, max_uid * sizeof *insn_addresses);
-  uid_align = (rtx *) xmalloc (max_uid * sizeof *uid_align);
-
-  varying_length = (char *) xmalloc (max_uid * sizeof (char));
+  insn_addresses = (int *) xcalloc (max_uid, sizeof (int));
 
-  bzero (varying_length, max_uid);
+  varying_length = (char *) xcalloc (max_uid, sizeof (char));
 
   /* Initialize uid_align.  We scan instructions
      from end to start, and keep in align_tab[n] the last seen insn
      that does an alignment of at least n+1, i.e. the successor
      in the alignment chain for an insn that does / has a known
      alignment of n.  */
-
-  bzero ((char *) uid_align, max_uid * sizeof *uid_align);
+  uid_align = (rtx *) xcalloc (max_uid, sizeof *uid_align);
 
   for (i = MAX_CODE_ALIGN; --i >= 0; )
     align_tab[i] = NULL_RTX;
@@ -2037,6 +2035,27 @@ final (first, file, optimize, prescan)
   free_insn_eh_region ();
 }
 \f
+const char *
+get_insn_template (code, insn)
+     int code;
+     rtx insn;
+{
+  const void *output = insn_data[code].output;
+  switch (insn_data[code].output_format)
+    {
+    case INSN_OUTPUT_FORMAT_SINGLE:
+      return (const char *) output;
+    case INSN_OUTPUT_FORMAT_MULTI:
+      return ((const char * const *) output)[which_alternative];
+    case INSN_OUTPUT_FORMAT_FUNCTION:
+      if (insn == NULL)
+       abort ();
+      return (* (insn_output_fn) output) (recog_data.operand, insn);
+
+    default:
+      abort ();
+    }
+}
 /* The final scan for one insn, INSN.
    Args are same as in `final', except that INSN
    is the insn being scanned.
@@ -2081,11 +2100,11 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
          && ! exceptions_via_longjmp)
        {
-         ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
+         ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_EH_HANDLER (insn));
           if (! flag_new_exceptions)
-            add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
+            add_eh_table_entry (NOTE_EH_HANDLER (insn));
 #ifdef ASM_OUTPUT_EH_REGION_BEG
-         ASM_OUTPUT_EH_REGION_BEG (file, NOTE_BLOCK_NUMBER (insn));
+         ASM_OUTPUT_EH_REGION_BEG (file, NOTE_EH_HANDLER (insn));
 #endif
          break;
        }
@@ -2093,11 +2112,11 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END
          && ! exceptions_via_longjmp)
        {
-         ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
+         ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_EH_HANDLER (insn));
           if (flag_new_exceptions)
-            add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
+            add_eh_table_entry (NOTE_EH_HANDLER (insn));
 #ifdef ASM_OUTPUT_EH_REGION_END
-         ASM_OUTPUT_EH_REGION_END (file, NOTE_BLOCK_NUMBER (insn));
+         ASM_OUTPUT_EH_REGION_END (file, NOTE_EH_HANDLER (insn));
 #endif
          break;
        }
@@ -2825,6 +2844,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 
 #endif
 
+#ifdef HAVE_peephole
        /* Do machine-specific peephole optimizations if desired.  */
 
        if (optimize && !flag_no_peephole && !nopeepholes)
@@ -2855,6 +2875,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
            /* PEEPHOLE might have changed this.  */
            body = PATTERN (insn);
          }
+#endif
 
        /* Try to recognize the instruction.
           If successful, verify that the operands satisfy the
@@ -2865,16 +2886,14 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        extract_insn (insn);
        cleanup_subreg_operands (insn);
 
-#ifdef REGISTER_CONSTRAINTS
        if (! constrain_operands (1))
          fatal_insn_not_found (insn);
-#endif
 
        /* Some target machines need to prescan each insn before
           it is output.  */
 
 #ifdef FINAL_PRESCAN_INSN
-       FINAL_PRESCAN_INSN (insn, recog_operand, recog_n_operands);
+       FINAL_PRESCAN_INSN (insn, recog_data.operand, recog_data.n_operands);
 #endif
 
 #ifdef HAVE_cc0
@@ -2896,24 +2915,18 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          dwarf2out_frame_debug (insn);
 #endif
 
-       /* If the proper template needs to be chosen by some C code,
-          run that code and get the real template.  */
+       /* Find the proper template for this insn.  */
+       template = get_insn_template (insn_code_number, insn);
 
-       template = insn_template[insn_code_number];
+       /* If the C code returns 0, it means that it is a jump insn
+          which follows a deleted test insn, and that test insn
+          needs to be reinserted.  */
        if (template == 0)
          {
-           template = (*insn_outfun[insn_code_number]) (recog_operand, insn);
-
-           /* If the C code returns 0, it means that it is a jump insn
-              which follows a deleted test insn, and that test insn
-              needs to be reinserted.  */
-           if (template == 0)
-             {
-               if (prev_nonnote_insn (insn) != last_ignored_compare)
-                 abort ();
-               new_block = 0;
-               return prev_nonnote_insn (insn);
-             }
+           if (prev_nonnote_insn (insn) != last_ignored_compare)
+             abort ();
+           new_block = 0;
+           return prev_nonnote_insn (insn);
          }
 
        /* If the template is the string "#", it means that this insn must
@@ -2942,7 +2955,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 
        /* Output assembler code from the template.  */
 
-       output_asm_insn (template, recog_operand);
+       output_asm_insn (template, recog_data.operand);
 
 #if defined (DWARF2_UNWIND_INFO)
 #if !defined (ACCUMULATE_OUTGOING_ARGS)
@@ -3051,22 +3064,22 @@ cleanup_subreg_operands (insn)
   int i;
 
   extract_insn (insn);
-  for (i = 0; i < recog_n_operands; i++)
+  for (i = 0; i < recog_data.n_operands; i++)
     {
-      if (GET_CODE (recog_operand[i]) == SUBREG)
-        recog_operand[i] = alter_subreg (recog_operand[i]);
-      else if (GET_CODE (recog_operand[i]) == PLUS
-               || GET_CODE (recog_operand[i]) == MULT)
-       recog_operand[i] = walk_alter_subreg (recog_operand[i]);
+      if (GET_CODE (recog_data.operand[i]) == SUBREG)
+        recog_data.operand[i] = alter_subreg (recog_data.operand[i]);
+      else if (GET_CODE (recog_data.operand[i]) == PLUS
+               || GET_CODE (recog_data.operand[i]) == MULT)
+       recog_data.operand[i] = walk_alter_subreg (recog_data.operand[i]);
     }
 
-  for (i = 0; i < recog_n_dups; i++)
+  for (i = 0; i < recog_data.n_dups; i++)
     {
-      if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
-        *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
-      else if (GET_CODE (*recog_dup_loc[i]) == PLUS
-               || GET_CODE (*recog_dup_loc[i]) == MULT)
-        *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
+      if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
+        *recog_data.dup_loc[i] = alter_subreg (*recog_data.dup_loc[i]);
+      else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
+               || GET_CODE (*recog_data.dup_loc[i]) == MULT)
+        *recog_data.dup_loc[i] = walk_alter_subreg (*recog_data.dup_loc[i]);
     }
 }
 
@@ -3089,6 +3102,7 @@ alter_subreg (x)
 
   if (GET_CODE (y) == REG)
     {
+      int regno;
       /* If the word size is larger than the size of this register,
         adjust the register number to compensate.  */
       /* ??? Note that this just catches stragglers created by/for
@@ -3096,13 +3110,14 @@ alter_subreg (x)
         earlier, or kept _all_ subregs until now and eliminate
         gen_lowpart and friends.  */
 
-      PUT_CODE (x, REG);
 #ifdef ALTER_HARD_SUBREG
-      REGNO (x) = ALTER_HARD_SUBREG(GET_MODE (x), SUBREG_WORD (x),
-                                   GET_MODE (y), REGNO (y));
+      regno = ALTER_HARD_SUBREG(GET_MODE (x), SUBREG_WORD (x),
+                               GET_MODE (y), REGNO (y));
 #else
-      REGNO (x) = REGNO (y) + SUBREG_WORD (x);
+      regno = REGNO (y) + SUBREG_WORD (x);
 #endif
+      PUT_CODE (x, REG);
+      REGNO (x) = regno;
       /* This field has a different meaning for REGs and SUBREGs.  Make sure
         to clear it!  */
       x->used = 0;
@@ -3357,11 +3372,13 @@ output_asm_name ()
        {
          register int num = INSN_CODE (debug_insn);
          fprintf (asm_out_file, "\t%s %d\t%s", 
-                  ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]);
-         if (insn_n_alternatives[num] > 1)
+                  ASM_COMMENT_START, INSN_UID (debug_insn),
+                  insn_data[num].name);
+         if (insn_data[num].n_alternatives > 1)
            fprintf (asm_out_file, "/%d", which_alternative + 1);
 #ifdef HAVE_ATTR_length
-         fprintf (asm_out_file, "\t[length = %d]", get_attr_length (debug_insn));
+         fprintf (asm_out_file, "\t[length = %d]",
+                  get_attr_length (debug_insn));
 #endif
          /* Clear this so only the first assembler insn
             of any rtl insn will get the special comment for -dp.  */
@@ -3864,6 +3881,7 @@ asm_fprintf VPROTO((FILE *file, const char *p, ...))
       default:
        fputc (c, file);
       }
+  va_end (argptr);
 }
 \f
 /* Split up a CONST_DOUBLE or integer constant rtx