OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 16 Aug 2009 17:25:23 +0000 (17:25 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 16 Aug 2009 17:25:23 +0000 (17:25 +0000)
* config/mips/mips-protos.h (mips_push_asm_switch): New function.
(mips_pop_asm_switch): Likewise.
* config/mips/mips.c (set_noreorder, set_nomacro, set_noat): Replace
with...
(mips_noreorder, mips_nomacro, mips_noat): ...these new variables.
(mips_push_asm_switch_1, mips_pop_asm_switch_1): New functions.
(mips_push_asm_switch, mips_pop_asm_switch): Likewise.
(mips_print_operand_punctuation): Use them.  Check mips_noreorder
instead of set_noreorder.
(mips_output_function_prologue): Use the new functions.
(mips_output_function_epilogue): Likewise.
(mips_need_noat_wrapper_p): New function, split out from...
(mips_final_prescan_insn, mips_final_postscan_insn): ...here.
Use mips_push_asm_switch and mips_pop_asm_switch.
* config/mips/mips.h (FUNCTION_PROFILER): Use mips_push_asm_switch
and mips_pop_asm_switch.
(ASM_OUTPUT_REG_POP): Likewise.
(DBR_OUTPUT_SEQEND): Remove boilerplate comment.
Use mips_pop_asm_switch.
(mips_asm_switch): New structure.
(set_noreorder, set_nomacro): Replace with...
(mips_noreorder, mips_nomacro, mips_noat): ...these new variables.
* config/mips/mips.md (fix_truncdfsi2_macro): Use mips_nomacro
instead of set_nomacro.
(fix_truncsfsi2_macro): Likewise.
(cprestore): Likewise.
(hazard): Use mips_noreorder instead of set_noreorder.
* config/mips/sdemtk.h (FUNCTION_PROFILER): As for mips.h.

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

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/config/mips/sdemtk.h

index 5a8aa36..a965bb2 100644 (file)
@@ -1,3 +1,34 @@
+2009-08-16  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/mips/mips-protos.h (mips_push_asm_switch): New function.
+       (mips_pop_asm_switch): Likewise.
+       * config/mips/mips.c (set_noreorder, set_nomacro, set_noat): Replace
+       with...
+       (mips_noreorder, mips_nomacro, mips_noat): ...these new variables.
+       (mips_push_asm_switch_1, mips_pop_asm_switch_1): New functions.
+       (mips_push_asm_switch, mips_pop_asm_switch): Likewise.
+       (mips_print_operand_punctuation): Use them.  Check mips_noreorder
+       instead of set_noreorder.
+       (mips_output_function_prologue): Use the new functions.
+       (mips_output_function_epilogue): Likewise.
+       (mips_need_noat_wrapper_p): New function, split out from...
+       (mips_final_prescan_insn, mips_final_postscan_insn): ...here.
+       Use mips_push_asm_switch and mips_pop_asm_switch.
+       * config/mips/mips.h (FUNCTION_PROFILER): Use mips_push_asm_switch
+       and mips_pop_asm_switch.
+       (ASM_OUTPUT_REG_POP): Likewise.
+       (DBR_OUTPUT_SEQEND): Remove boilerplate comment.
+       Use mips_pop_asm_switch.
+       (mips_asm_switch): New structure.
+       (set_noreorder, set_nomacro): Replace with...
+       (mips_noreorder, mips_nomacro, mips_noat): ...these new variables.
+       * config/mips/mips.md (fix_truncdfsi2_macro): Use mips_nomacro
+       instead of set_nomacro.
+       (fix_truncsfsi2_macro): Likewise.
+       (cprestore): Likewise.
+       (hazard): Use mips_noreorder instead of set_noreorder.
+       * config/mips/sdemtk.h (FUNCTION_PROFILER): As for mips.h.
+
 2009-08-16  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/alpha/alpha.c (alpha_and_function): Handle NULL_RTX returned
index 40ffd7f..d350259 100644 (file)
@@ -254,6 +254,8 @@ extern void mips_conditional_register_usage (void);
 extern void mips_order_regs_for_local_alloc (void);
 extern HOST_WIDE_INT mips_debugger_offset (rtx, HOST_WIDE_INT);
 
+extern void mips_push_asm_switch (struct mips_asm_switch *);
+extern void mips_pop_asm_switch (struct mips_asm_switch *);
 extern void mips_print_operand (FILE *, rtx, int);
 extern void mips_print_operand_address (FILE *, rtx);
 extern void mips_output_external (FILE *, tree, const char *);
index 2dd0118..572d6e7 100644 (file)
@@ -440,9 +440,9 @@ int mips_dbx_regno[FIRST_PSEUDO_REGISTER];
 int mips_dwarf_regno[FIRST_PSEUDO_REGISTER];
 
 /* The nesting depth of the PRINT_OPERAND '%(', '%<' and '%[' constructs.  */
-int set_noreorder;
-int set_nomacro;
-static int set_noat;
+struct mips_asm_switch mips_noreorder = { "reorder", 0 };
+struct mips_asm_switch mips_nomacro = { "macro", 0 };
+struct mips_asm_switch mips_noat = { "at", 0 };
 
 /* True if we're writing out a branch-likely instruction rather than a
    normal branch.  */
@@ -6989,6 +6989,45 @@ mips_print_operand_reloc (FILE *file, rtx op, enum mips_symbol_context context,
       fputc (')', file);
 }
 
+/* Start a new block with the given asm switch enabled.  If we need
+   to print a directive, emit PREFIX before it and SUFFIX after it.  */
+
+static void
+mips_push_asm_switch_1 (struct mips_asm_switch *asm_switch,
+                       const char *prefix, const char *suffix)
+{
+  if (asm_switch->nesting_level == 0)
+    fprintf (asm_out_file, "%s.set\tno%s%s", prefix, asm_switch->name, suffix);
+  asm_switch->nesting_level++;
+}
+
+/* Likewise, but end a block.  */
+
+static void
+mips_pop_asm_switch_1 (struct mips_asm_switch *asm_switch,
+                      const char *prefix, const char *suffix)
+{
+  gcc_assert (asm_switch->nesting_level);
+  asm_switch->nesting_level--;
+  if (asm_switch->nesting_level == 0)
+    fprintf (asm_out_file, "%s.set\t%s%s", prefix, asm_switch->name, suffix);
+}
+
+/* Wrappers around mips_push_asm_switch_1 and mips_pop_asm_switch_1
+   that either print a complete line or print nothing.  */
+
+void
+mips_push_asm_switch (struct mips_asm_switch *asm_switch)
+{
+  mips_push_asm_switch_1 (asm_switch, "\t", "\n");
+}
+
+void
+mips_pop_asm_switch (struct mips_asm_switch *asm_switch)
+{
+  mips_pop_asm_switch_1 (asm_switch, "\t", "\n");
+}
+
 /* Print the text for PRINT_OPERAND punctation character CH to FILE.
    The punctuation characters are:
 
@@ -7019,36 +7058,27 @@ mips_print_operand_punctuation (FILE *file, int ch)
   switch (ch)
     {
     case '(':
-      if (set_noreorder++ == 0)
-       fputs (".set\tnoreorder\n\t", file);
+      mips_push_asm_switch_1 (&mips_noreorder, "", "\n\t");
       break;
 
     case ')':
-      gcc_assert (set_noreorder > 0);
-      if (--set_noreorder == 0)
-       fputs ("\n\t.set\treorder", file);
+      mips_pop_asm_switch_1 (&mips_noreorder, "\n\t", "");
       break;
 
     case '[':
-      if (set_noat++ == 0)
-       fputs (".set\tnoat\n\t", file);
+      mips_push_asm_switch_1 (&mips_noat, "", "\n\t");
       break;
 
     case ']':
-      gcc_assert (set_noat > 0);
-      if (--set_noat == 0)
-       fputs ("\n\t.set\tat", file);
+      mips_pop_asm_switch_1 (&mips_noat, "\n\t", "");
       break;
 
     case '<':
-      if (set_nomacro++ == 0)
-       fputs (".set\tnomacro\n\t", file);
+      mips_push_asm_switch_1 (&mips_nomacro, "", "\n\t");
       break;
 
     case '>':
-      gcc_assert (set_nomacro > 0);
-      if (--set_nomacro == 0)
-       fputs ("\n\t.set\tmacro", file);
+      mips_pop_asm_switch_1 (&mips_nomacro, "\n\t", "");
       break;
 
     case '*':
@@ -7060,7 +7090,7 @@ mips_print_operand_punctuation (FILE *file, int ch)
       break;
 
     case '#':
-      if (set_noreorder != 0)
+      if (mips_noreorder.nesting_level > 0)
        fputs ("\n\tnop", file);
       break;
 
@@ -7068,7 +7098,7 @@ mips_print_operand_punctuation (FILE *file, int ch)
       /* Print an extra newline so that the delayed insn is separated
         from the following ones.  This looks neater and is consistent
         with non-nop delayed sequences.  */
-      if (set_noreorder != 0 && final_sequence == 0)
+      if (mips_noreorder.nesting_level > 0 && final_sequence == 0)
        fputs ("\n\tnop\n", file);
       break;
 
@@ -9267,14 +9297,23 @@ mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
          output_asm_insn ("sll\t$2,16", 0);
          output_asm_insn ("addu\t$2,$3", 0);
        }
-      /* .cpload must be in a .set noreorder but not a .set nomacro block.  */
-      else if (!cfun->machine->all_noreorder_p)
-       output_asm_insn ("%(.cpload\t%^%)", 0);
       else
-       output_asm_insn ("%(.cpload\t%^\n\t%<", 0);
+       {
+         /* .cpload must be in a .set noreorder but not a
+            .set nomacro block.  */
+         mips_push_asm_switch (&mips_noreorder);
+         output_asm_insn (".cpload\t%^", 0);
+         if (!cfun->machine->all_noreorder_p)
+           mips_pop_asm_switch (&mips_noreorder);
+         else
+           mips_push_asm_switch (&mips_nomacro);
+       }
     }
   else if (cfun->machine->all_noreorder_p)
-    output_asm_insn ("%(%<", 0);
+    {
+      mips_push_asm_switch (&mips_noreorder);
+      mips_push_asm_switch (&mips_nomacro);
+    }
 
   /* Tell the assembler which register we're using as the global
      pointer.  This is needed for thunks, since they can use either
@@ -9296,10 +9335,8 @@ mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
 
   if (cfun->machine->all_noreorder_p)
     {
-      /* Avoid using %>%) since it adds excess whitespace.  */
-      output_asm_insn (".set\tmacro", 0);
-      output_asm_insn (".set\treorder", 0);
-      set_noreorder = set_nomacro = 0;
+      mips_pop_asm_switch (&mips_nomacro);
+      mips_pop_asm_switch (&mips_noreorder);
     }
 
   /* Get the function name the same way that toplev.c does before calling
@@ -14763,36 +14800,38 @@ mips_at_reg_p (rtx *x, void *data ATTRIBUTE_UNUSED)
   return REG_P (*x) && REGNO (*x) == AT_REGNUM;
 }
 
+/* Return true if INSN needs to be wrapped in ".set noat".
+   INSN has NOPERANDS operands, stored in OPVEC.  */
 
-/* Implement FINAL_PRESCAN_INSN.  */
-
-void
-mips_final_prescan_insn (rtx insn, rtx *opvec, int noperands)
+static bool
+mips_need_noat_wrapper_p (rtx insn, rtx *opvec, int noperands)
 {
   int i;
 
-  /* We need to emit ".set noat" before an instruction that accesses
-     $1 (AT).  */
   if (recog_memoized (insn) >= 0)
     for (i = 0; i < noperands; i++)
       if (for_each_rtx (&opvec[i], mips_at_reg_p, NULL))
-       if (set_noat++ == 0)
-         fprintf (asm_out_file, "\t.set\tnoat\n");
+       return true;
+  return false;
+}
+
+/* Implement FINAL_PRESCAN_INSN.  */
+
+void
+mips_final_prescan_insn (rtx insn, rtx *opvec, int noperands)
+{
+  if (mips_need_noat_wrapper_p (insn, opvec, noperands))
+    mips_push_asm_switch (&mips_noat);
 }
 
 /* Implement TARGET_ASM_FINAL_POSTSCAN_INSN.  */
 
 static void
-mips_final_postscan_insn (FILE *file, rtx insn, rtx *opvec, int noperands)
+mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED, rtx insn,
+                         rtx *opvec, int noperands)
 {
-  int i;
-
-  /* Close any ".set noat" block opened by mips_final_prescan_insn.  */
-  if (recog_memoized (insn) >= 0)
-    for (i = 0; i < noperands; i++)
-      if (for_each_rtx (&opvec[i], mips_at_reg_p, NULL))
-       if (--set_noat == 0)
-         fprintf (file, "\t.set\tat\n");
+  if (mips_need_noat_wrapper_p (insn, opvec, noperands))
+    mips_pop_asm_switch (&mips_noat);
 }
 \f
 /* Initialize the GCC target structure.  */
index 89f9056..76ab40a 100644 (file)
@@ -2364,7 +2364,7 @@ typedef struct mips_args {
       else                                                             \
        fprintf (FILE, "\tla\t%s,_mcount\n", reg_names[GP_REG_FIRST + 3]); \
     }                                                                  \
-  fprintf (FILE, "\t.set\tnoat\n");                                    \
+  mips_push_asm_switch (&mips_noat);                                   \
   fprintf (FILE, "\tmove\t%s,%s\t\t# save current return address\n",   \
           reg_names[GP_REG_FIRST + 1], reg_names[GP_REG_FIRST + 31]);  \
   /* _mcount treats $2 as the static chain register.  */               \
@@ -2384,7 +2384,7 @@ typedef struct mips_args {
     fprintf (FILE, "\tjalr\t%s\n", reg_names[GP_REG_FIRST + 3]);       \
   else                                                                 \
     fprintf (FILE, "\tjal\t_mcount\n");                                        \
-  fprintf (FILE, "\t.set\tat\n");                                      \
+  mips_pop_asm_switch (&mips_noat);                                    \
   /* _mcount treats $2 as the static chain register.  */               \
   if (cfun->static_chain_decl != NULL)                                 \
     fprintf (FILE, "\tmove\t%s,%s\n", reg_names[STATIC_CHAIN_REGNUM],  \
@@ -2778,32 +2778,13 @@ typedef struct mips_args {
 #define PRINT_OPERAND_PUNCT_VALID_P(CODE) mips_print_operand_punct[CODE]
 #define PRINT_OPERAND_ADDRESS mips_print_operand_address
 
-/* A C statement, to be executed after all slot-filler instructions
-   have been output.  If necessary, call `dbr_sequence_length' to
-   determine the number of slots filled in a sequence (zero if not
-   currently outputting a sequence), to decide how many no-ops to
-   output, or whatever.
-
-   Don't define this macro if it has nothing to do, but it is
-   helpful in reading assembly output if the extent of the delay
-   sequence is made explicit (e.g. with white space).
-
-   Note that output routines for instructions with delay slots must
-   be prepared to deal with not being output as part of a sequence
-   (i.e.  when the scheduling pass is not run, or when no slot
-   fillers could be found.)  The variable `final_sequence' is null
-   when not processing a sequence, otherwise it contains the
-   `sequence' rtx being output.  */
-
 #define DBR_OUTPUT_SEQEND(STREAM)                                      \
 do                                                                     \
   {                                                                    \
-    if (set_nomacro > 0 && --set_nomacro == 0)                         \
-      fputs ("\t.set\tmacro\n", STREAM);                               \
-                                                                       \
-    if (set_noreorder > 0 && --set_noreorder == 0)                     \
-      fputs ("\t.set\treorder\n", STREAM);                             \
-                                                                       \
+    /* Undo the effect of '%*'.  */                                    \
+    mips_pop_asm_switch (&mips_nomacro);                               \
+    mips_pop_asm_switch (&mips_noreorder);                             \
+    /* Emit a blank line after the delay slot for emphasis.  */                \
     fputs ("\n", STREAM);                                              \
   }                                                                    \
 while (0)
@@ -2996,9 +2977,7 @@ while (0)
 #define ASM_OUTPUT_REG_POP(STREAM,REGNO)                               \
 do                                                                     \
   {                                                                    \
-    if (! set_noreorder)                                               \
-      fprintf (STREAM, "\t.set\tnoreorder\n");                         \
-                                                                       \
+    mips_push_asm_switch (&mips_noreorder);                            \
     fprintf (STREAM, "\t%s\t%s,0(%s)\n\t%s\t%s,%s,8\n",                        \
             TARGET_64BIT ? "ld" : "lw",                                \
             reg_names[REGNO],                                          \
@@ -3006,9 +2985,7 @@ do                                                                        \
             TARGET_64BIT ? "daddu" : "addu",                           \
             reg_names[STACK_POINTER_REGNUM],                           \
             reg_names[STACK_POINTER_REGNUM]);                          \
-                                                                       \
-    if (! set_noreorder)                                               \
-      fprintf (STREAM, "\t.set\treorder\n");                           \
+    mips_pop_asm_switch (&mips_noreorder);                             \
   }                                                                    \
 while (0)
 
@@ -3406,13 +3383,23 @@ while (0)
 #define MIPS_SYNC_EXCHANGE_12_NONZERO_OP "\tor\t%@,%@,%4\n"
 
 #ifndef USED_FOR_TARGET
+/* Information about ".set noFOO; ...; .set FOO" blocks.  */
+struct mips_asm_switch {
+  /* The FOO in the description above.  */
+  const char *name;
+
+  /* The current block nesting level, or 0 if we aren't in a block.  */
+  int nesting_level;
+};
+
 extern const enum reg_class mips_regno_to_class[];
 extern bool mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
 extern bool mips_print_operand_punct[256];
 extern const char *current_function_file; /* filename current function is in */
 extern int num_source_filenames;       /* current .file # */
-extern int set_noreorder;              /* # of nested .set noreorder's  */
-extern int set_nomacro;                        /* # of nested .set nomacro's  */
+extern struct mips_asm_switch mips_noreorder;
+extern struct mips_asm_switch mips_nomacro;
+extern struct mips_asm_switch mips_noat;
 extern int mips_dbx_regno[];
 extern int mips_dwarf_regno[];
 extern bool mips_split_p[];
index bbea6f3..77f1fe7 100644 (file)
    (clobber (match_scratch:DF 2 "=d"))]
   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
 {
-  if (set_nomacro)
+  if (mips_nomacro.nesting_level > 0)
     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
   else
     return "trunc.w.d %0,%1,%2";
    (clobber (match_scratch:SF 2 "=d"))]
   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
 {
-  if (set_nomacro)
+  if (mips_nomacro.nesting_level > 0)
     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
   else
     return "trunc.w.s %0,%1,%2";
                    UNSPEC_CPRESTORE)]
   ""
 {
-  if (set_nomacro && which_alternative == 1)
+  if (mips_nomacro.nesting_level > 0 && which_alternative == 1)
     return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
   else
     return ".cprestore\t%0";
   [(const_int 1)]
   ""
   {
-    if (set_noreorder)
+    if (mips_noreorder.nesting_level > 0)
       return "nop";
     else
       return "#nop";
index adaaa25..27dab06 100644 (file)
@@ -93,7 +93,7 @@ extern void mips_sync_icache (void *beg, unsigned long len);
 #undef FUNCTION_PROFILER
 #define FUNCTION_PROFILER(FILE, LABELNO)                               \
   {                                                                    \
-    fprintf (FILE, "\t.set\tnoat\n");                                  \
+    mips_push_asm_switch (&mips_noat);                                 \
     /* _mcount treats $2 as the static chain register.  */             \
     if (cfun->static_chain_decl != NULL)                               \
       fprintf (FILE, "\tmove\t%s,%s\n", reg_names[2],                  \
@@ -103,7 +103,7 @@ extern void mips_sync_icache (void *beg, unsigned long len);
             reg_names[GP_REG_FIRST + (TARGET_MIPS16 ? 3 : 1)],         \
             reg_names[GP_REG_FIRST + 31]);                             \
     fprintf (FILE, "\tjal\t_mcount\n");                                        \
-    fprintf (FILE, "\t.set\tat\n");                                    \
+    mips_pop_asm_switch (&mips_noat);                                  \
     /* _mcount treats $2 as the static chain register.  */             \
     if (cfun->static_chain_decl != NULL)                               \
       fprintf (FILE, "\tmove\t%s,%s\n", reg_names[STATIC_CHAIN_REGNUM],        \