summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-10 18:20:22 +0000
committerchaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-10 18:20:22 +0000
commite6554c42242a8dc22b42317cdb19e5485cdf58c8 (patch)
tree6e37fe7e1f86ddb16c584d6ceb5493f7b05e1620
parentf81220715b6ac7af398bc9e5acb7386c996e1a54 (diff)
downloadgcc-e6554c42242a8dc22b42317cdb19e5485cdf58c8.tar.gz
2009-04-10 Chao-ying Fu <fu@mips.com>
* doc/tm.texi (Instruction Output): Document TARGET_ASM_FINAL_POSTSCAN_INSN. * target.h (final_postscan_insn): New field in asm_out. * target-def.h (TARGET_ASM_FINAL_POSTSCAN_INSN): New define. (TARGET_ASM_OUT): Add TARGET_ASM_FINAL_POSTSCAN_INSN. * final.c (final_scan_insn): Call targetm.asm_out.final_postscan_insn after outputting an asm macro and a normal instruction. * config/mips/mips.h (FINAL_PRESCAN_INSN): New define. * config/mips/mips-protos.h (mips_final_prescan_insn): Declare. * config/mips/mips.c (mips_at_reg_p): New for_each_rtx callback. (mips_final_prescan_insn, mips_final_postscan_insn): New functions. (TARGET_ASM_FINAL_POSTSCAN_INSN): New define. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145934 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c43
-rw-r--r--gcc/config/mips/mips.h3
-rw-r--r--gcc/doc/tm.texi13
-rw-r--r--gcc/final.c10
-rw-r--r--gcc/target-def.h7
-rw-r--r--gcc/target.h2
8 files changed, 95 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a77df07a6af..9965730d134 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+2009-04-10 Chao-ying Fu <fu@mips.com>
+
+ * doc/tm.texi (Instruction Output): Document
+ TARGET_ASM_FINAL_POSTSCAN_INSN.
+ * target.h (final_postscan_insn): New field in asm_out.
+ * target-def.h (TARGET_ASM_FINAL_POSTSCAN_INSN): New define.
+ (TARGET_ASM_OUT): Add TARGET_ASM_FINAL_POSTSCAN_INSN.
+ * final.c (final_scan_insn): Call
+ targetm.asm_out.final_postscan_insn after outputting
+ an asm macro and a normal instruction.
+
+ * config/mips/mips.h (FINAL_PRESCAN_INSN): New define.
+ * config/mips/mips-protos.h (mips_final_prescan_insn): Declare.
+ * config/mips/mips.c (mips_at_reg_p): New for_each_rtx callback.
+ (mips_final_prescan_insn, mips_final_postscan_insn): New functions.
+ (TARGET_ASM_FINAL_POSTSCAN_INSN): New define.
+
2009-04-10 Paolo Bonzini <bonzini@gnu.org>
PR middle-end/39701
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index a704750286b..1f8054ede9c 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -333,5 +333,6 @@ extern void mips_expand_atomic_qihi (union mips_gen_fn_ptrs,
extern void mips_expand_vector_init (rtx, rtx);
extern bool mips_epilogue_uses (unsigned int);
+extern void mips_final_prescan_insn (rtx, rtx *, int);
#endif /* ! GCC_MIPS_PROTOS_H */
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 9912105ecfa..0b51c78f576 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -14697,6 +14697,46 @@ mips_epilogue_uses (unsigned int regno)
return false;
}
+
+/* A for_each_rtx callback. Stop the search if *X is an AT register. */
+
+static int
+mips_at_reg_p (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+ return GET_CODE (*x) == REG && REGNO (*x) == AT_REGNUM;
+}
+
+
+/* Implement FINAL_PRESCAN_INSN. */
+
+void
+mips_final_prescan_insn (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");
+}
+
+/* Implement TARGET_ASM_FINAL_POSTSCAN_INSN. */
+
+void
+mips_final_postscan_insn (FILE *file, 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");
+}
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -14865,6 +14905,9 @@ mips_epilogue_uses (unsigned int regno)
#undef TARGET_IRA_COVER_CLASSES
#define TARGET_IRA_COVER_CLASSES mips_ira_cover_classes
+#undef TARGET_ASM_FINAL_POSTSCAN_INSN
+#define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-mips.h"
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index fbcfdca61e9..45971acf08a 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -3459,3 +3459,6 @@ extern enum mips_code_readable_setting mips_code_readable;
/* Enable querying of DFA units. */
#define CPU_UNITS_QUERY 1
+
+#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
+ mips_final_prescan_insn (INSN, OPVEC, NOPERANDS)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 665b2693e2f..0396a706cf7 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -8193,6 +8193,19 @@ writing conditional output routines in those patterns.
If this macro is not defined, it is equivalent to a null statement.
@end defmac
+@deftypefn {Target Hook} void TARGET_ASM_FINAL_POSTSCAN_INSN (FILE *@var{FILE}, rtx @var{insn}, rtx *@var{opvec}, int @var{noperands})
+If defined, this target hook is a function which is executed just after the
+output of assembler code for @var{insn}, to change the mode of the assembler
+if necessary.
+
+Here the argument @var{opvec} is the vector containing the operands
+extracted from @var{insn}, and @var{noperands} is the number of
+elements of the vector which contain meaningful data for this insn.
+The contents of this vector are what was used to convert the insn
+template into assembler code, so you can change the assembler mode
+by checking the contents of the vector.
+@end deftypefn
+
@defmac PRINT_OPERAND (@var{stream}, @var{x}, @var{code})
A C compound statement to output to stdio stream @var{stream} the
assembler syntax for an instruction operand @var{x}. @var{x} is an
diff --git a/gcc/final.c b/gcc/final.c
index 1735a73207d..32d6b74e8f1 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2235,6 +2235,10 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
#endif
}
+ if (targetm.asm_out.final_postscan_insn)
+ targetm.asm_out.final_postscan_insn (file, insn, ops,
+ insn_noperands);
+
this_is_asm_operands = 0;
break;
}
@@ -2637,6 +2641,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
/* Output assembler code from the template. */
output_asm_insn (templ, recog_data.operand);
+ /* Some target machines need to postscan each insn after
+ it is output. */
+ if (targetm.asm_out.final_postscan_insn)
+ targetm.asm_out.final_postscan_insn (file, insn, recog_data.operand,
+ recog_data.n_operands);
+
/* If necessary, report the effect that the instruction has on
the unwind info. We've already done this for delay slots
and call instructions. */
diff --git a/gcc/target-def.h b/gcc/target-def.h
index e19cde3f0a2..9e6693bbb88 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -236,6 +236,10 @@
#define TARGET_ASM_OUTPUT_DWARF_DTPREL NULL
#endif
+#ifndef TARGET_ASM_FINAL_POSTSCAN_INSN
+#define TARGET_ASM_FINAL_POSTSCAN_INSN NULL
+#endif
+
#ifndef TARGET_ASM_RECORD_GCC_SWITCHES
#define TARGET_ASM_RECORD_GCC_SWITCHES NULL
#endif
@@ -291,7 +295,8 @@
TARGET_ASM_RECORD_GCC_SWITCHES, \
TARGET_ASM_RECORD_GCC_SWITCHES_SECTION, \
TARGET_ASM_OUTPUT_ANCHOR, \
- TARGET_ASM_OUTPUT_DWARF_DTPREL}
+ TARGET_ASM_OUTPUT_DWARF_DTPREL, \
+ TARGET_ASM_FINAL_POSTSCAN_INSN}
/* Scheduler hooks. All of these default to null pointers, which
haifa-sched.c looks for and handles. */
diff --git a/gcc/target.h b/gcc/target.h
index 4fb379465cf..a520e1c5765 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -245,6 +245,8 @@ struct gcc_target
/* Output a DTP-relative reference to a TLS symbol. */
void (*output_dwarf_dtprel) (FILE *file, int size, rtx x);
+ /* Some target machines need to postscan each insn after it is output. */
+ void (*final_postscan_insn) (FILE *, rtx, rtx *, int);
} asm_out;
/* Functions relating to instruction scheduling. */