* 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
+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
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 */
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");
+}
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#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;
\f
#include "gt-mips.h"
/* Enable querying of DFA units. */
#define CPU_UNITS_QUERY 1
+
+#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
+ mips_final_prescan_insn (INSN, OPVEC, NOPERANDS)
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
#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;
}
/* 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. */
#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
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. */
/* 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. */