From: Richard Sandiford Date: Sun, 16 Aug 2009 17:25:23 +0000 (+0000) Subject: mips-protos.h (mips_push_asm_switch): New function. X-Git-Tag: releases/gcc-4.5.0~3999 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cf5fb4b0d5ef246c8aa90fea9439c696c8462b8f;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a8aa3620d3f..a965bb2f2a49 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2009-08-16 Richard Sandiford + + * 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 * config/alpha/alpha.c (alpha_and_function): Handle NULL_RTX returned diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 40ffd7fd7d1f..d35025942216 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -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 *); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 2dd01184775f..572d6e7d40cf 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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); } /* Initialize the GCC target structure. */ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 89f905621258..76ab40a1e57b 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -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[]; diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index bbea6f3401ec..77f1fe769087 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -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"; diff --git a/gcc/config/mips/sdemtk.h b/gcc/config/mips/sdemtk.h index adaaa25e6cde..27dab06f2982 100644 --- a/gcc/config/mips/sdemtk.h +++ b/gcc/config/mips/sdemtk.h @@ -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], \