mips-protos.h (mips_push_asm_switch): New function.

gcc/
	* 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.

From-SVN: r150803
This commit is contained in:
Richard Sandiford 2009-08-16 17:25:23 +00:00 committed by Richard Sandiford
parent 3eb96d01d4
commit cf5fb4b0d5
6 changed files with 145 additions and 86 deletions

View 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

View 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 *);

View 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. */
static bool
mips_need_noat_wrapper_p (rtx insn, rtx *opvec, int noperands)
{
int i;
if (recog_memoized (insn) >= 0)
for (i = 0; i < noperands; i++)
if (for_each_rtx (&opvec[i], mips_at_reg_p, NULL))
return true;
return false;
}
/* 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");
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);
}
/* Initialize the GCC target structure. */

View 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[];

View File

@ -3204,7 +3204,7 @@
(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";
@ -3241,7 +3241,7 @@
(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";
@ -4790,7 +4790,7 @@
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";
@ -6259,7 +6259,7 @@
[(const_int 1)]
""
{
if (set_noreorder)
if (mips_noreorder.nesting_level > 0)
return "nop";
else
return "#nop";

View 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], \