From: Joshua Kinard Date: Sat, 15 Nov 2008 14:26:07 +0000 (+0000) Subject: invoke.texi (-mfix-r10000): Document. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ee9a72e50cf00a988023f8eb2b08d25da87a7643;p=gcc.git invoke.texi (-mfix-r10000): Document. gcc/ 2008-11-15 Joshua Kinard * doc/invoke.texi (-mfix-r10000): Document. * config/mips/mips.opt (mfix-r10000): New option. * config/mips/mips-protos.h (mips_output_sync_loop): Declare. * config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Use %?. (MIPS_COMPARE_AND_SWAP_12): Likewise. (MIPS_SYNC_OP): Likewise. (MIPS_SYNC_OP_12): Likewise. (MIPS_SYNC_OLD_OP_12): Likewise. (MIPS_SYNC_NEW_OP_12): Likewise. (MIPS_SYNC_OLD_OP): Likewise. (MIPS_SYNC_NAND): Likewise. (MIPS_SYNC_OLD_NAND): Likewise. (MIPS_SYNC_EXCHANGE): Likewise. (MIPS_SYNC_EXCHANGE_12): Likewise. (MIPS_SYNC_NEW_OP): Likewise, using %~ to fill branch-likely delay slots. (MIPS_SYNC_NEW_NAND): Likewise. * config/mips/mips.c (mips_print_operand_punctuation): Handle '~'. (mips_init_print_operand_punct): Treat '~' as a punctuation character. (mips_output_sync_loop): New function. (mips_override_options): Make -march=r10000 imply -mfix-r10000. Make -mfix-r10000 require branch-likely instructions. * config/mips/sync.md (sync_compare_and_swap): Use mips_output_sync_loop. (compare_and_swap_12): Likewise. (sync_add): Likewise. (sync__12): Likewise. (sync_old__12): Likewise. (sync_new__12): Likewise. (sync_nand_12): Likewise. (sync_old_nand_12): Likewise. (sync_new_nand_12): Likewise. (sync_sub): Likewise. (sync_old_add): Likewise. (sync_old_sub): Likewise. (sync_new_add): Likewise. (sync_new_sub): Likewise. (sync_): Likewise. (sync_old_): Likewise. (sync_new_): Likewise. (sync_nand): Likewise. (sync_old_nand): Likewise. (sync_new_nand): Likewise. (sync_lock_test_and_set): Likewise. (test_and_set_12): Likewise. gcc/testsuite/ 2008-11-15 Joshua Kinard Richard Sandiford * gcc.target/mips/fix-r10000-1.c: New test. * gcc.target/mips/fix-r10000-2.c: Likewise. * gcc.target/mips/fix-r10000-3.c: Likewise. * gcc.target/mips/fix-r10000-4.c: Likewise. * gcc.target/mips/fix-r10000-5.c: Likewise. * gcc.target/mips/fix-r10000-6.c: Likewise. * gcc.target/mips/fix-r10000-7.c: Likewise. * gcc.target/mips/fix-r10000-8.c: Likewise. * gcc.target/mips/fix-r10000-9.c: Likewise. * gcc.target/mips/fix-r10000-10.c: Likewise. * gcc.target/mips/fix-r10000-11.c: Likewise. * gcc.target/mips/fix-r10000-12.c: Likewise. * gcc.target/mips/fix-r10000-13.c: Likewise. * gcc.target/mips/fix-r10000-14.c: Likewise. * gcc.target/mips/fix-r10000-15.c: Likewise. Co-Authored-By: Richard Sandiford From-SVN: r141886 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c9d65c06c3..a4e4609f57d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,51 @@ +2008-11-15 Joshua Kinard + + * doc/invoke.texi (-mfix-r10000): Document. + * config/mips/mips.opt (mfix-r10000): New option. + * config/mips/mips-protos.h (mips_output_sync_loop): Declare. + * config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Use %?. + (MIPS_COMPARE_AND_SWAP_12): Likewise. + (MIPS_SYNC_OP): Likewise. + (MIPS_SYNC_OP_12): Likewise. + (MIPS_SYNC_OLD_OP_12): Likewise. + (MIPS_SYNC_NEW_OP_12): Likewise. + (MIPS_SYNC_OLD_OP): Likewise. + (MIPS_SYNC_NAND): Likewise. + (MIPS_SYNC_OLD_NAND): Likewise. + (MIPS_SYNC_EXCHANGE): Likewise. + (MIPS_SYNC_EXCHANGE_12): Likewise. + (MIPS_SYNC_NEW_OP): Likewise, using %~ to fill branch-likely + delay slots. + (MIPS_SYNC_NEW_NAND): Likewise. + * config/mips/mips.c (mips_print_operand_punctuation): Handle '~'. + (mips_init_print_operand_punct): Treat '~' as a punctuation character. + (mips_output_sync_loop): New function. + (mips_override_options): Make -march=r10000 imply -mfix-r10000. + Make -mfix-r10000 require branch-likely instructions. + * config/mips/sync.md (sync_compare_and_swap): Use + mips_output_sync_loop. + (compare_and_swap_12): Likewise. + (sync_add): Likewise. + (sync__12): Likewise. + (sync_old__12): Likewise. + (sync_new__12): Likewise. + (sync_nand_12): Likewise. + (sync_old_nand_12): Likewise. + (sync_new_nand_12): Likewise. + (sync_sub): Likewise. + (sync_old_add): Likewise. + (sync_old_sub): Likewise. + (sync_new_add): Likewise. + (sync_new_sub): Likewise. + (sync_): Likewise. + (sync_old_): Likewise. + (sync_new_): Likewise. + (sync_nand): Likewise. + (sync_old_nand): Likewise. + (sync_new_nand): Likewise. + (sync_lock_test_and_set): Likewise. + (test_and_set_12): Likewise. + 2008-11-15 Eric Botcazou * gcc.c (cc1_options): Fix comment. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 9403945a4f3..3fa67c982ea 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -300,6 +300,7 @@ extern const char *mips_output_load_label (void); extern const char *mips_output_conditional_branch (rtx, rtx *, const char *, const char *); extern const char *mips_output_order_conditional_branch (rtx, rtx *, bool); +extern const char *mips_output_sync_loop (const char *); extern const char *mips_output_division (const char *, rtx *); extern unsigned int mips_hard_regno_nregs (int, enum machine_mode); extern bool mips_linked_madd_p (rtx, rtx); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index fa78c8bf270..5198fd32ddc 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -6909,6 +6909,7 @@ mips_print_operand_reloc (FILE *file, rtx op, enum mips_symbol_context context, '#' Print a nop if in a ".set noreorder" block. '/' Like '#', but do nothing within a delayed-branch sequence. '?' Print "l" if mips_branch_likely is true + '~' Print a nop if mips_branch_likely is true '.' Print the name of the register with a hard-wired zero (zero or $0). '@' Print the name of the assembler temporary register (at or $1). '^' Print the name of the pic call-through register (t9 or $25). @@ -6983,6 +6984,11 @@ mips_print_operand_punctuation (FILE *file, int ch) putc ('l', file); break; + case '~': + if (mips_branch_likely) + fputs ("\n\tnop", file); + break; + case '.': fputs (reg_names[GP_REG_FIRST + 0], file); break; @@ -7026,7 +7032,7 @@ mips_init_print_operand_punct (void) { const char *p; - for (p = "()[]<>*#/?.@^+$|-"; *p; p++) + for (p = "()[]<>*#/?~.@^+$|-"; *p; p++) mips_print_operand_punct[(unsigned char) *p] = true; } @@ -10250,6 +10256,17 @@ mips_output_order_conditional_branch (rtx insn, rtx *operands, bool inverted_p) return mips_output_conditional_branch (insn, operands, branch[1], branch[0]); } +/* Return the assembly code for __sync_*() loop LOOP. The loop should support + both normal and likely branches, using %? and %~ where appropriate. */ + +const char * +mips_output_sync_loop (const char *loop) +{ + /* Use branch-likely instructions to work around the LL/SC R10000 errata. */ + mips_branch_likely = TARGET_FIX_R10000; + return loop; +} + /* Return the assembly code for DIV or DDIV instruction DIVISION, which has the operands given by OPERANDS. Add in a divide-by-zero check if needed. @@ -13971,6 +13988,24 @@ mips_override_options (void) && mips_matching_cpu_name_p (mips_arch_info->name, "r4400")) target_flags |= MASK_FIX_R4400; + /* Default to working around R10000 errata only if the processor + was selected explicitly. */ + if ((target_flags_explicit & MASK_FIX_R10000) == 0 + && mips_matching_cpu_name_p (mips_arch_info->name, "r10000")) + target_flags |= MASK_FIX_R10000; + + /* Make sure that branch-likely instructions available when using + -mfix-r10000. The instructions are not available if either: + + 1. -mno-branch-likely was passed. + 2. The selected ISA does not support branch-likely and + the command line does not include -mbranch-likely. */ + if (TARGET_FIX_R10000 + && ((target_flags_explicit & MASK_BRANCHLIKELY) == 0 + ? !ISA_HAS_BRANCHLIKELY + : !TARGET_BRANCHLIKELY)) + sorry ("%qs requires branch-likely instructions", "-mfix-r10000"); + /* Save base state of options. */ mips_base_target_flags = target_flags; mips_base_delayed_branch = flag_delayed_branch; diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 354c4c5f1c3..8ae2b206fae 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -3090,7 +3090,7 @@ while (0) "\tbne\t%0,%z2,2f\n" \ "\t" OP "\t%@,%3\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)\n" \ "2:\n" @@ -3115,7 +3115,7 @@ while (0) "\tand\t%@,%0,%3\n" \ OPS \ "\tsc\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)\n" \ "2:\n" @@ -3135,7 +3135,7 @@ while (0) "1:\tll" SUFFIX "\t%@,%0\n" \ "\t" INSN "\t%@,%@,%1\n" \ "\tsc" SUFFIX "\t%@,%0\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3160,7 +3160,7 @@ while (0) "\tand\t%4,%4,%1\n" \ "\tor\t%@,%@,%4\n" \ "\tsc\t%@,%0\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3193,7 +3193,7 @@ while (0) "\tand\t%5,%5,%2\n" \ "\tor\t%@,%@,%5\n" \ "\tsc\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3223,7 +3223,7 @@ while (0) "\tand\t%0,%0,%2\n" \ "\tor\t%@,%@,%0\n" \ "\tsc\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3243,7 +3243,7 @@ while (0) "1:\tll" SUFFIX "\t%0,%1\n" \ "\t" INSN "\t%@,%0,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3260,7 +3260,7 @@ while (0) "1:\tll" SUFFIX "\t%0,%1\n" \ "\t" INSN "\t%@,%0,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b%~\n" \ "\t" INSN "\t%0,%0,%2\n" \ "\tsync%-%]%>%)" @@ -3277,7 +3277,7 @@ while (0) "\tnor\t%@,%@,%.\n" \ "\t" INSN "\t%@,%@,%1\n" \ "\tsc" SUFFIX "\t%@,%0\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3296,7 +3296,7 @@ while (0) "\tnor\t%@,%0,%.\n" \ "\t" INSN "\t%@,%@,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3315,7 +3315,7 @@ while (0) "\tnor\t%0,%0,%.\n" \ "\t" INSN "\t%@,%0,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b%~\n" \ "\t" INSN "\t%0,%0,%2\n" \ "\tsync%-%]%>%)" @@ -3333,7 +3333,7 @@ while (0) "1:\tll" SUFFIX "\t%0,%1\n" \ "\t" OP "\t%@,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3357,7 +3357,7 @@ while (0) "\tand\t%@,%0,%3\n" \ OPS \ "\tsc\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index f192f0b52b8..c7e78ff5d13 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -112,6 +112,10 @@ mfix-r4400 Target Report Mask(FIX_R4400) Work around certain R4400 errata +mfix-r10000 +Target Report Mask(FIX_R10000) +Work around certain R10000 errata + mfix-sb1 Target Report Var(TARGET_FIX_SB1) Work around errata for early SB-1 revision 2 cores diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md index 0052f46dc9f..286ca369214 100644 --- a/gcc/config/mips/sync.md +++ b/gcc/config/mips/sync.md @@ -43,9 +43,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_COMPARE_AND_SWAP ("", "li"); + return mips_output_sync_loop (MIPS_COMPARE_AND_SWAP ("", "li")); else - return MIPS_COMPARE_AND_SWAP ("", "move"); + return mips_output_sync_loop (MIPS_COMPARE_AND_SWAP ("", "move")); } [(set_attr "length" "32")]) @@ -76,9 +76,11 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_NONZERO_OP); + return (mips_output_sync_loop + (MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_NONZERO_OP))); else - return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_ZERO_OP); + return (mips_output_sync_loop + (MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_ZERO_OP))); } [(set_attr "length" "40,36")]) @@ -91,9 +93,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OP ("", "addiu"); + return mips_output_sync_loop (MIPS_SYNC_OP ("", "addiu")); else - return MIPS_SYNC_OP ("", "addu"); + return mips_output_sync_loop (MIPS_SYNC_OP ("", "addu")); } [(set_attr "length" "28")]) @@ -124,7 +126,8 @@ (clobber (match_scratch:SI 4 "=&d"))] "GENERATE_LL_SC" { - return MIPS_SYNC_OP_12 ("", MIPS_SYNC_OP_12_NOT_NOP); + return (mips_output_sync_loop + (MIPS_SYNC_OP_12 ("", MIPS_SYNC_OP_12_NOT_NOP))); } [(set_attr "length" "40")]) @@ -160,8 +163,9 @@ (clobber (match_scratch:SI 5 "=&d"))] "GENERATE_LL_SC" { - return MIPS_SYNC_OLD_OP_12 ("", MIPS_SYNC_OLD_OP_12_NOT_NOP, - MIPS_SYNC_OLD_OP_12_NOT_NOP_REG); + return (mips_output_sync_loop + (MIPS_SYNC_OLD_OP_12 ("", MIPS_SYNC_OLD_OP_12_NOT_NOP, + MIPS_SYNC_OLD_OP_12_NOT_NOP_REG))); } [(set_attr "length" "40")]) @@ -202,7 +206,8 @@ (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))] "GENERATE_LL_SC" { - return MIPS_SYNC_NEW_OP_12 ("", MIPS_SYNC_NEW_OP_12_NOT_NOP); + return (mips_output_sync_loop + (MIPS_SYNC_NEW_OP_12 ("", MIPS_SYNC_NEW_OP_12_NOT_NOP))); } [(set_attr "length" "40")]) @@ -233,7 +238,8 @@ (clobber (match_scratch:SI 4 "=&d"))] "GENERATE_LL_SC" { - return MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT); + return (mips_output_sync_loop + (MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT))); } [(set_attr "length" "44")]) @@ -267,8 +273,9 @@ (clobber (match_scratch:SI 5 "=&d"))] "GENERATE_LL_SC" { - return MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT, - MIPS_SYNC_OLD_OP_12_NOT_NOT_REG); + return (mips_output_sync_loop + (MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT, + MIPS_SYNC_OLD_OP_12_NOT_NOT_REG))); } [(set_attr "length" "44")]) @@ -307,7 +314,8 @@ (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))] "GENERATE_LL_SC" { - return MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT); + return (mips_output_sync_loop + (MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT))); } [(set_attr "length" "40")]) @@ -319,7 +327,7 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { - return MIPS_SYNC_OP ("", "subu"); + return mips_output_sync_loop (MIPS_SYNC_OP ("", "subu")); } [(set_attr "length" "28")]) @@ -334,9 +342,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OLD_OP ("", "addiu"); + return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("", "addiu")); else - return MIPS_SYNC_OLD_OP ("", "addu"); + return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("", "addu")); } [(set_attr "length" "28")]) @@ -350,7 +358,7 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { - return MIPS_SYNC_OLD_OP ("", "subu"); + return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("", "subu")); } [(set_attr "length" "28")]) @@ -365,9 +373,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_NEW_OP ("", "addiu"); + return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("", "addiu")); else - return MIPS_SYNC_NEW_OP ("", "addu"); + return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("", "addu")); } [(set_attr "length" "28")]) @@ -381,7 +389,7 @@ UNSPEC_SYNC_NEW_OP))] "GENERATE_LL_SC" { - return MIPS_SYNC_NEW_OP ("", "subu"); + return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("", "subu")); } [(set_attr "length" "28")]) @@ -394,9 +402,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OP ("", ""); + return mips_output_sync_loop (MIPS_SYNC_OP ("", "")); else - return MIPS_SYNC_OP ("", ""); + return mips_output_sync_loop (MIPS_SYNC_OP ("", "")); } [(set_attr "length" "28")]) @@ -411,9 +419,10 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OLD_OP ("", ""); + return (mips_output_sync_loop + (MIPS_SYNC_OLD_OP ("", ""))); else - return MIPS_SYNC_OLD_OP ("", ""); + return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("", "")); } [(set_attr "length" "28")]) @@ -428,9 +437,10 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_NEW_OP ("", ""); + return (mips_output_sync_loop + (MIPS_SYNC_NEW_OP ("", ""))); else - return MIPS_SYNC_NEW_OP ("", ""); + return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("", "")); } [(set_attr "length" "28")]) @@ -441,9 +451,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_NAND ("", "andi"); + return mips_output_sync_loop (MIPS_SYNC_NAND ("", "andi")); else - return MIPS_SYNC_NAND ("", "and"); + return mips_output_sync_loop (MIPS_SYNC_NAND ("", "and")); } [(set_attr "length" "32")]) @@ -456,9 +466,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OLD_NAND ("", "andi"); + return mips_output_sync_loop (MIPS_SYNC_OLD_NAND ("", "andi")); else - return MIPS_SYNC_OLD_NAND ("", "and"); + return mips_output_sync_loop (MIPS_SYNC_OLD_NAND ("", "and")); } [(set_attr "length" "32")]) @@ -471,9 +481,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_NEW_NAND ("", "andi"); + return mips_output_sync_loop (MIPS_SYNC_NEW_NAND ("", "andi")); else - return MIPS_SYNC_NEW_NAND ("", "and"); + return mips_output_sync_loop (MIPS_SYNC_NEW_NAND ("", "and")); } [(set_attr "length" "32")]) @@ -486,9 +496,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_EXCHANGE ("", "li"); + return mips_output_sync_loop (MIPS_SYNC_EXCHANGE ("", "li")); else - return MIPS_SYNC_EXCHANGE ("", "move"); + return mips_output_sync_loop (MIPS_SYNC_EXCHANGE ("", "move")); } [(set_attr "length" "24")]) @@ -516,8 +526,10 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_NONZERO_OP); + return (mips_output_sync_loop + (MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_NONZERO_OP))); else - return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_ZERO_OP); + return (mips_output_sync_loop + (MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_ZERO_OP))); } [(set_attr "length" "28,24")]) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ce621520fce..cc66b45c14b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -668,8 +668,8 @@ Objective-C and Objective-C++ Dialects}. -mmemcpy -mno-memcpy -mlong-calls -mno-long-calls @gol -mmad -mno-mad -mfused-madd -mno-fused-madd -nocpp @gol -mfix-r4000 -mno-fix-r4000 -mfix-r4400 -mno-fix-r4400 @gol --mfix-vr4120 -mno-fix-vr4120 -mfix-vr4130 -mno-fix-vr4130 @gol --mfix-sb1 -mno-fix-sb1 @gol +-mfix-r10000 -mno-fix-r10000 -mfix-vr4120 -mno-fix-vr4120 @gol +-mfix-vr4130 -mno-fix-vr4130 -mfix-sb1 -mno-fix-sb1 @gol -mflush-func=@var{func} -mno-flush-func @gol -mbranch-cost=@var{num} -mbranch-likely -mno-branch-likely @gol -mfp-exceptions -mno-fp-exceptions @gol @@ -12833,6 +12833,22 @@ A double-word or a variable shift may give an incorrect result if executed immediately after starting an integer division. @end itemize +@item -mfix-r10000 +@itemx -mno-fix-r10000 +@opindex mfix-r10000 +@opindex mno-fix-r10000 +Work around certain R10000 errata: +@itemize @minus +@item +@code{ll}/@code{sc} sequences may not behave atomically on revisions +prior to 3.0. They may deadlock on revisions 2.6 and earlier. +@end itemize + +This option can only be used if the target architecture supports +branch-likely instructions. @option{-mfix-r10000} is the default when +@option{-march=r10000} is used; @option{-mno-fix-r10000} is the default +otherwise. + @item -mfix-vr4120 @itemx -mno-fix-vr4120 @opindex mfix-vr4120 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b64bf6356f7..1a4a0d29fe2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,22 @@ +2008-11-15 Joshua Kinard + Richard Sandiford + + * gcc.target/mips/fix-r10000-1.c: New test. + * gcc.target/mips/fix-r10000-2.c: Likewise. + * gcc.target/mips/fix-r10000-3.c: Likewise. + * gcc.target/mips/fix-r10000-4.c: Likewise. + * gcc.target/mips/fix-r10000-5.c: Likewise. + * gcc.target/mips/fix-r10000-6.c: Likewise. + * gcc.target/mips/fix-r10000-7.c: Likewise. + * gcc.target/mips/fix-r10000-8.c: Likewise. + * gcc.target/mips/fix-r10000-9.c: Likewise. + * gcc.target/mips/fix-r10000-10.c: Likewise. + * gcc.target/mips/fix-r10000-11.c: Likewise. + * gcc.target/mips/fix-r10000-12.c: Likewise. + * gcc.target/mips/fix-r10000-13.c: Likewise. + * gcc.target/mips/fix-r10000-14.c: Likewise. + * gcc.target/mips/fix-r10000-15.c: Likewise. + 2008-11-15 Jakub Jelinek PR c++/37561 diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-1.c b/gcc/testsuite/gcc.target/mips/fix-r10000-1.c new file mode 100644 index 00000000000..e72974befc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_fetch_and_add (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_fetch_and_add (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_fetch_and_add (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-10.c b/gcc/testsuite/gcc.target/mips/fix-r10000-10.c new file mode 100644 index 00000000000..a6dbfa3dfc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-10.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_and_and_fetch (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_and_and_fetch (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_and_and_fetch (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-11.c b/gcc/testsuite/gcc.target/mips/fix-r10000-11.c new file mode 100644 index 00000000000..4bf16e175a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-11.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_xor_and_fetch (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_xor_and_fetch (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_xor_and_fetch (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-12.c b/gcc/testsuite/gcc.target/mips/fix-r10000-12.c new file mode 100644 index 00000000000..0381c249e45 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-12.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_nand_and_fetch (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_nand_and_fetch (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_nand_and_fetch (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-13.c b/gcc/testsuite/gcc.target/mips/fix-r10000-13.c new file mode 100644 index 00000000000..7e1efc85ab9 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-13.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_bool_compare_and_swap (z, 0, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_bool_compare_and_swap (z, 0, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_bool_compare_and_swap (z, 0, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-14.c b/gcc/testsuite/gcc.target/mips/fix-r10000-14.c new file mode 100644 index 00000000000..8d8fe095e34 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-14.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_val_compare_and_swap (z, 0, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_val_compare_and_swap (z, 0, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_val_compare_and_swap (z, 0, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-15.c b/gcc/testsuite/gcc.target/mips/fix-r10000-15.c new file mode 100644 index 00000000000..fd7d0364bd7 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-15.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + int result; + + result = __sync_lock_test_and_set (z, 42); + __sync_lock_release (z); + return result; +} + +NOMIPS16 short +f2 (short *z) +{ + short result; + + result = __sync_lock_test_and_set (z, 42); + __sync_lock_release (z); + return result; +} + +NOMIPS16 char +f3 (char *z) +{ + char result; + + result = __sync_lock_test_and_set (z, 42); + __sync_lock_release (z); + return result; +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-2.c b/gcc/testsuite/gcc.target/mips/fix-r10000-2.c new file mode 100644 index 00000000000..900a697c99e --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-2.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z, int amt) +{ + return __sync_fetch_and_sub (z, amt); +} + +NOMIPS16 short +f2 (short *z, short amt) +{ + return __sync_fetch_and_sub (z, amt); +} + +NOMIPS16 char +f3 (char *z, char amt) +{ + return __sync_fetch_and_sub (z, amt); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-3.c b/gcc/testsuite/gcc.target/mips/fix-r10000-3.c new file mode 100644 index 00000000000..de74e9724ee --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-3.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_fetch_and_or (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_fetch_and_or (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_fetch_and_or (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-4.c b/gcc/testsuite/gcc.target/mips/fix-r10000-4.c new file mode 100644 index 00000000000..0c962ee267f --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-4.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_fetch_and_and (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_fetch_and_and (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_fetch_and_and (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-5.c b/gcc/testsuite/gcc.target/mips/fix-r10000-5.c new file mode 100644 index 00000000000..15a0704f2c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-5.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_fetch_and_xor (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_fetch_and_xor (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_fetch_and_xor (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-6.c b/gcc/testsuite/gcc.target/mips/fix-r10000-6.c new file mode 100644 index 00000000000..275136957c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-6.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_fetch_and_nand (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_fetch_and_nand (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_fetch_and_nand (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-7.c b/gcc/testsuite/gcc.target/mips/fix-r10000-7.c new file mode 100644 index 00000000000..bbe985695da --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-7.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_add_and_fetch (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_add_and_fetch (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_add_and_fetch (z, 42); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-8.c b/gcc/testsuite/gcc.target/mips/fix-r10000-8.c new file mode 100644 index 00000000000..6e990a63fa6 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-8.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z, int amt) +{ + return __sync_sub_and_fetch (z, amt); +} + +NOMIPS16 short +f2 (short *z, short amt) +{ + return __sync_sub_and_fetch (z, amt); +} + +NOMIPS16 char +f3 (char *z, char amt) +{ + return __sync_sub_and_fetch (z, amt); +} diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-9.c b/gcc/testsuite/gcc.target/mips/fix-r10000-9.c new file mode 100644 index 00000000000..8373c42d949 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fix-r10000-9.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */ +/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */ + +NOMIPS16 int +f1 (int *z) +{ + return __sync_or_and_fetch (z, 42); +} + +NOMIPS16 short +f2 (short *z) +{ + return __sync_or_and_fetch (z, 42); +} + +NOMIPS16 char +f3 (char *z) +{ + return __sync_or_and_fetch (z, 42); +}