This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch] MIPS: Add option to enable/disable atomic memory primitives.
- From: David Daney <ddaney at avtrex dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, richard at codesourcery dot com
- Date: Mon, 10 Sep 2007 15:37:06 -0700
- Subject: Re: [Patch] MIPS: Add option to enable/disable atomic memory primitives.
- References: <46E4EDFE.40908@avtrex.com> <87ir6i7j5z.fsf@firetop.home>
Richard Sandiford wrote:
Thanks for doing this.
--with-llsc=llsc and --with-llsc=no-llsc seem odd from a user-interface
perspective, although I agree using "llsc" and "no-llsc" as the %(VALUE)
in OPTION_DEFAULT_SPECS is the right thing. Would it make sense to document
the options as --with-llsc and --without-llsc and remove "llsc" and "no-llsc"
from the config.gcc case statement? Something like:
---------------------------------------------------------------------------
@item --with-llsc
On MIPS targets, make @option{-mllsc} the default when no @option{-mno-llsc}
option is passed. This is the default for Linux-based targets, because the
kernel will emulate the instructions if the ISA does not provide them.
@item --without-llsc
On MIPS targets, make @option{-mno-llsc} the default when no @option{-mllsc}
option is passed.
...
@item -mllsc
@itemx -mno-llsc
@opindex mllsc
@opindex mno-llsc
Use (do not use) the @samp{ll}, @samp{sc}, and @samp{sync} instructions
to implement atomic memory built-in functions. When neither option is
specified, GCC will use the instructions if the target architecture
supports them.
@option{-mllsc} is useful if the runtime environment can emulate the
instructions and @option{-mno-llsc} can be useful when compiling for
nonstandard ISAs. You can make either option the default by configuring
GCC with @option{--with-llsc} and @option{--without-llsc} respectively.
@option{--with-llsc} is the default for some configurations; see the
installation documentation for details.
---------------------------------------------------------------------------
(I realise it's probably more friendly to describe the options in more
detail in the --with* block, but duplicated descriptions so often get
out of sync.)
Right, I pretty much plagiarized your wording.
For consistency, the macros you've renamed to ISA_HAS_FOO_DEFAULT
should stay ISA_HAS_FOO, and your new ISA_HAS_FOO macros should be
GENERATE_FOO. (I also have a mild preference for LLSC_FROM_ISA
rather than LLSC_DEFAULT, as it might make the code a little easier
to understand. Don't change it if you don't agree though.)
OK, I think I did pretty much what you suggest.
David Daney <ddaney@avtrex.com> writes:
@@ -627,7 +627,7 @@ Objective-C and Objective-C++ Dialects}.
-msingle-float -mdouble-float -mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol
-msmartmips -mno-smartmips @gol
-mpaired-single -mno-paired-single -mdmx -mno-mdmx @gol
--mips3d -mno-mips3d -mmt -mno-mt @gol
+-mips3d -mno-mips3d -mmt -mno-mt -mllsc -mno-llsc @gol
-mlong64 -mlong32 -msym32 -mno-sym32 @gol
-G@var{num} -mlocal-sdata -mno-local-sdata @gol
-mextern-sdata -mno-extern-sdata -mgpopt -mno-gopt @gol
Options should be separated by two spaces.
Fixed.
@@ -6167,6 +6179,16 @@ print_operand (FILE *file, rtx op, int l
}
break;
+ case '|':
+ if (mips_llsc == LLSC_YES && !ISA_HAS_LL_SC_DEFAULT)
+ fputs (".set\tpush\n\t.set\tmips2\n\t", file);
+ break;
+
+ case '-':
+ if (mips_llsc == LLSC_YES && !ISA_HAS_LL_SC_DEFAULT)
+ fputs (".set\tpop\n\t", file);
+ break;
+
default:
error ("PRINT_OPERAND: unknown punctuation '%c'", letter);
break;
Watch the identation.
Whoops. Incompetent .emacs author lead to this. Now fixed.
Might as well drop the mips_llsc check;
if you want to make sure we're only generating them when expected,
we should gcc_assert, rather than rely on the assembler to complain.
I think dropping the check is sufficient.
New version attached.
Currently building/testing on mipsel-linux.
OK to commit if no regressions?
2007-09-09 David Daney <ddaney@avtrex.com>
* doc/invoke.texi: Document new MIPS -mllsc and -mno-llsc options.
* doc/install.texi: Document new --with-llsc and --without-llsc
options.
* config.gcc: Handle --with-llsc and --without-llsc configure options.
* config/mips/mips.md (sync, memory_barrier): Wrap sync instrunction
in %| and %- operand codes. Depend on GENERATE_SYNC instead of
ISA_HAS_SYNC.
(sync_compare_and_swap<mode>, sync_add<mode>, sync_sub<mode>,
sync_old_add<mode>, sync_old_sub<mode>, sync_new_add<mode>,
sync_new_sub<mode>, sync_<optab><mode>, sync_old_<optab><mode>,
sync_new_<optab><mode>, sync_nand<mode>, sync_old_nand<mode>,
sync_new_nand<mode>, sync_lock_test_and_set<mode>): Depend on
GENERATE_LL_SC instead of ISA_HAS_LL_SC.
* config/mips/mips.opt (mllsc): New option.
* config/mips/mips.c (mips_llsc): Define variable.
(mips_handle_option): Handle mllsc option.
(override_options): Set mips_print_operand_punct for '|' and '-'.
(print_operand): Add new %| and %- operand codes.
* config/mips/mips.h (mips_llsc_setting): New enum type.
(mips_llsc): Declare.
(OPTION_DEFAULT_SPECS): Add llsc handling.
(GENERATE_SYNC): New macro.
(GENERATE_LL_SC): New macro.
(MIPS_COMPARE_AND_SWAP, MIPS_SYNC_OP, MIPS_SYNC_OLD_OP,
MIPS_SYNC_NEW_OP, MIPS_SYNC_NAND, MIPS_SYNC_OLD_NAND,
MIPS_SYNC_NEW_NAND, MIPS_SYNC_EXCHANGE): Wrap instructions
in %| and %- operand codes.
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi (revision 128349)
+++ doc/invoke.texi (working copy)
@@ -627,7 +627,7 @@ Objective-C and Objective-C++ Dialects}.
-msingle-float -mdouble-float -mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol
-msmartmips -mno-smartmips @gol
-mpaired-single -mno-paired-single -mdmx -mno-mdmx @gol
--mips3d -mno-mips3d -mmt -mno-mt @gol
+-mips3d -mno-mips3d -mmt -mno-mt -mllsc -mno-llsc @gol
-mlong64 -mlong32 -msym32 -mno-sym32 @gol
-G@var{num} -mlocal-sdata -mno-local-sdata @gol
-mextern-sdata -mno-extern-sdata -mgpopt -mno-gopt @gol
@@ -11772,6 +11772,22 @@ operations.
Assume that the floating-point coprocessor supports double-precision
operations. This is the default.
+@item -mllsc
+@itemx -mno-llsc
+@opindex mllsc
+@opindex mno-llsc
+Use (do not use) @samp{ll}, @samp{sc}, and @samp{sync} instructions to
+implement atomic memory built-in functions. When neither option is
+specified, GCC will use the instructions if the target architecture
+supports them.
+
+@option{-mllsc} is useful if the runtime environment can emulate the
+instructions and @option{-mno-llsc} can be useful when compiling for
+nonstandard ISAs. You can make either option the default by
+configuring GCC with @option{--with-llsc} and @option{--without-llsc}
+respectively. @option{--with-llsc} is the default for some
+configurations; see the installation documentation for details.
+
@item -mdsp
@itemx -mno-dsp
@opindex mdsp
Index: doc/install.texi
===================================================================
--- doc/install.texi (revision 128349)
+++ doc/install.texi (working copy)
@@ -1062,6 +1062,16 @@ systems that support conditional traps).
Division by zero checks use the break instruction.
@end table
+@item --with-llsc
+On MIPS targets, make @option{-mllsc} the default when no
+@option{-mno-lsc} option is passed. This is the default for
+Linux-based targets, as the kernel will emulate them if the ISA does
+not provide them.
+
+@item --without-llsc
+On MIPS targets, make @option{-mno-llsc} the default when no
+@option{-mllsc} option is passed.
+
@item --enable-__cxa_atexit
Define if you want to use __cxa_atexit, rather than atexit, to
register C++ destructors for local statics and global objects.
@@ -3610,6 +3620,17 @@ configure for @samp{mipsel-elf} as a wor
@samp{mips*-*-linux*} target continues to use the MIPS II routines. More
work on this is expected in future releases.
+The built-in @code{__sync_*} functions are available on MIPS II and
+later systems and others that support the @samp{ll}, @samp{sc} and
+@samp{sync} instructions. This can be overridden by passing
+@option{--with-llsc} or @option{--without-llsc} when configuring GCC.
+Since the Linux kernel emulates these instructions if they are
+missing, the default for @samp{mips*-*-linux*} targets is
+@option{--with-llsc}. The @option{--with-llsc} and
+@option{--without-llsc} configure options may be overridden at compile
+time by passing the @option{-mllsc} or @option{-mno-llsc} options to
+the compiler.
+
MIPS systems check for division by zero (unless
@option{-mno-check-zero-division} is passed to the compiler) by
generating either a conditional trap or a break instruction. Using
Index: config.gcc
===================================================================
--- config.gcc (revision 128349)
+++ config.gcc (working copy)
@@ -1663,6 +1663,7 @@ mips64*-*-linux*)
tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32"
gnu_ld=yes
gas=yes
+ test x$with_llsc != x || with_llsc=yes
;;
mips*-*-linux*) # Linux MIPS, either endian.
tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h"
@@ -1672,6 +1673,7 @@ mips*-*-linux*) # Linux MIPS, either
tm_defines="${tm_defines} MIPS_ISA_DEFAULT=32"
;;
esac
+ test x$with_llsc != x || with_llsc=yes
;;
mips*-*-openbsd*)
tm_defines="${tm_defines} OBSD_HAS_DECLARE_FUNCTION_NAME OBSD_HAS_DECLARE_OBJECT OBSD_HAS_CORRECT_SPECS"
@@ -3008,7 +3010,7 @@ case "${target}" in
;;
mips*-*-*)
- supported_defaults="abi arch float tune divide"
+ supported_defaults="abi arch float tune divide llsc"
case ${with_float} in
"" | soft | hard)
@@ -3037,6 +3039,23 @@ case "${target}" in
*)
echo "Unknown division check type use in --with-divide=$with_divide" 1>&2
exit 1
+ ;;
+ esac
+
+ case ${with_llsc} in
+ yes)
+ with_llsc=llsc
+ ;;
+ no)
+ with_llsc="no-llsc"
+ ;;
+ "")
+ # OK
+ ;;
+ *)
+ echo "Unknown llsc type used in --with-llsc" 1>&2
+ exit 1
+ ;;
esac
;;
@@ -3301,7 +3320,7 @@ case ${target} in
esac
t=
-all_defaults="abi cpu arch tune schedule float mode fpu divide"
+all_defaults="abi cpu arch tune schedule float mode fpu divide llsc"
for option in $all_defaults
do
eval "val=\$with_$option"
Index: config/mips/mips.md
===================================================================
--- config/mips/mips.md (revision 128349)
+++ config/mips/mips.md (working copy)
@@ -4270,8 +4270,8 @@ (define_expand "clear_cache"
(define_insn "sync"
[(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
- "ISA_HAS_SYNC"
- "sync")
+ "GENERATE_SYNC"
+ "%|sync\n\t%-")
(define_insn "synci"
[(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
@@ -4308,8 +4308,8 @@ (define_insn "clear_hazard"
(define_insn "memory_barrier"
[(set (mem:BLK (scratch))
(unspec:BLK [(const_int 0)] UNSPEC_MEMORY_BARRIER))]
- "ISA_HAS_SYNC"
- "sync")
+ "GENERATE_SYNC"
+ "%|sync\n\t%-")
(define_insn "sync_compare_and_swap<mode>"
[(set (match_operand:GPR 0 "register_operand" "=&d,d")
@@ -4318,7 +4318,7 @@ (define_insn "sync_compare_and_swap<mode
(unspec_volatile:GPR [(match_operand:GPR 2 "register_operand" "d,d")
(match_operand:GPR 3 "arith_operand" "I,d")]
UNSPEC_COMPARE_AND_SWAP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_COMPARE_AND_SWAP ("<d>", "li");
@@ -4333,7 +4333,7 @@ (define_insn "sync_add<mode>"
[(plus:GPR (match_dup 0)
(match_operand:GPR 1 "arith_operand" "I,d"))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OP ("<d>", "<d>addiu");
@@ -4348,7 +4348,7 @@ (define_insn "sync_sub<mode>"
[(minus:GPR (match_dup 0)
(match_operand:GPR 1 "register_operand" "d"))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
return MIPS_SYNC_OP ("<d>", "<d>subu");
}
@@ -4362,7 +4362,7 @@ (define_insn "sync_old_add<mode>"
[(plus:GPR (match_dup 1)
(match_operand:GPR 2 "arith_operand" "I,d"))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OLD_OP ("<d>", "<d>addiu");
@@ -4379,7 +4379,7 @@ (define_insn "sync_old_sub<mode>"
[(minus:GPR (match_dup 1)
(match_operand:GPR 2 "register_operand" "d"))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
return MIPS_SYNC_OLD_OP ("<d>", "<d>subu");
}
@@ -4393,7 +4393,7 @@ (define_insn "sync_new_add<mode>"
(unspec_volatile:GPR
[(plus:GPR (match_dup 1) (match_dup 2))]
UNSPEC_SYNC_NEW_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_NEW_OP ("<d>", "<d>addiu");
@@ -4410,7 +4410,7 @@ (define_insn "sync_new_sub<mode>"
(unspec_volatile:GPR
[(minus:GPR (match_dup 1) (match_dup 2))]
UNSPEC_SYNC_NEW_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
return MIPS_SYNC_NEW_OP ("<d>", "<d>subu");
}
@@ -4422,7 +4422,7 @@ (define_insn "sync_<optab><mode>"
[(fetchop_bit:GPR (match_operand:GPR 1 "uns_arith_operand" "K,d")
(match_dup 0))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OP ("<d>", "<immediate_insn>");
@@ -4439,7 +4439,7 @@ (define_insn "sync_old_<optab><mode>"
[(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
(match_dup 1))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OLD_OP ("<d>", "<immediate_insn>");
@@ -4456,7 +4456,7 @@ (define_insn "sync_new_<optab><mode>"
[(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
(match_dup 1))]
UNSPEC_SYNC_NEW_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_NEW_OP ("<d>", "<immediate_insn>");
@@ -4469,7 +4469,7 @@ (define_insn "sync_nand<mode>"
[(set (match_operand:GPR 0 "memory_operand" "+R,R")
(unspec_volatile:GPR [(match_operand:GPR 1 "uns_arith_operand" "K,d")]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_NAND ("<d>", "andi");
@@ -4484,7 +4484,7 @@ (define_insn "sync_old_nand<mode>"
(set (match_dup 1)
(unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OLD_NAND ("<d>", "andi");
@@ -4499,7 +4499,7 @@ (define_insn "sync_new_nand<mode>"
(set (match_dup 1)
(unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
UNSPEC_SYNC_NEW_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_NEW_NAND ("<d>", "andi");
@@ -4514,7 +4514,7 @@ (define_insn "sync_lock_test_and_set<mod
(set (match_dup 1)
(unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")]
UNSPEC_SYNC_EXCHANGE))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_EXCHANGE ("<d>", "li");
Index: config/mips/mips.opt
===================================================================
--- config/mips/mips.opt (revision 128349)
+++ config/mips/mips.opt (working copy)
@@ -176,6 +176,10 @@ mips3d
Target Report RejectNegative Mask(MIPS3D)
Use MIPS-3D instructions
+mllsc
+Target Report
+Use (or don't use) ll, sc and sync instructions
+
mlocal-sdata
Target Report Var(TARGET_LOCAL_SDATA) Init(1)
Use -G for object-local data
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c (revision 128349)
+++ config/mips/mips.c (working copy)
@@ -635,6 +635,9 @@ static GTY(()) int mips16_flipper;
/* The -mtext-loads setting. */
enum mips_code_readable_setting mips_code_readable = CODE_READABLE_YES;
+/* The -mllsc setting. */
+enum mips_llsc_setting mips_llsc = LLSC_DEFAULT;
+
/* The architecture selected by -mipsN. */
static const struct mips_cpu_info *mips_isa_info;
@@ -5346,7 +5349,7 @@ mips_set_current_function (tree fndecl A
/* Implement TARGET_HANDLE_OPTION. */
static bool
-mips_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
+mips_handle_option (size_t code, const char *arg, int value)
{
switch (code)
{
@@ -5388,6 +5391,10 @@ mips_handle_option (size_t code, const c
return false;
return true;
+ case OPT_mllsc:
+ mips_llsc = value ? LLSC_YES : LLSC_NO;
+ return true;
+
default:
return true;
}
@@ -5650,6 +5657,8 @@ override_options (void)
mips_print_operand_punct['$'] = 1;
mips_print_operand_punct['+'] = 1;
mips_print_operand_punct['~'] = 1;
+ mips_print_operand_punct['|'] = 1;
+ mips_print_operand_punct['-'] = 1;
/* Set up array to map GCC register number to debug register number.
Ignore the special purpose register numbers. */
@@ -6012,7 +6021,10 @@ mips_strip_unspec_address (rtx op)
'^' Print the name of the pic call-through register (t9 or $25).
'$' Print the name of the stack pointer register (sp or $29).
'+' Print the name of the gp register (usually gp or $28).
- '~' Output a branch alignment to LABEL_ALIGN(NULL). */
+ '~' Output a branch alignment to LABEL_ALIGN(NULL).
+ '|' Print .set push; .set mips2 if mips_llsc == LLSC_YES
+ && !ISA_HAS_LL_SC_DEFAULT.
+ '-' Print .set pop under the same conditions for '|'. */
void
print_operand (FILE *file, rtx op, int letter)
@@ -6142,6 +6154,16 @@ print_operand (FILE *file, rtx op, int l
}
break;
+ case '|':
+ if (!ISA_HAS_LL_SC)
+ fputs (".set\tpush\n\t.set\tmips2\n\t", file);
+ break;
+
+ case '-':
+ if (!ISA_HAS_LL_SC)
+ fputs (".set\tpop\n\t", file);
+ break;
+
default:
error ("PRINT_OPERAND: unknown punctuation '%c'", letter);
break;
Index: config/mips/mips.h
===================================================================
--- config/mips/mips.h (revision 128349)
+++ config/mips/mips.h (working copy)
@@ -121,6 +121,14 @@ enum mips_code_readable_setting {
CODE_READABLE_YES
};
+
+/* Enumerates the setting of the -mllsc option. */
+enum mips_llsc_setting {
+ LLSC_DEFAULT,
+ LLSC_NO,
+ LLSC_YES
+};
+
#ifndef USED_FOR_TARGET
extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */
extern const char *current_function_file; /* filename current function is in */
@@ -145,6 +153,7 @@ extern const struct mips_cpu_info *mips_
extern const struct mips_cpu_info *mips_tune_info;
extern const struct mips_rtx_cost_data *mips_cost;
extern enum mips_code_readable_setting mips_code_readable;
+extern enum mips_llsc_setting mips_llsc;
#endif
/* Macros to silence warnings about numbers being signed in traditional
@@ -688,7 +697,8 @@ extern enum mips_code_readable_setting m
{"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
{"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
{"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
- {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }
+ {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
+ {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }
#define GENERATE_DIVIDE_TRAPS (TARGET_DIVIDE_TRAPS \
@@ -893,11 +903,15 @@ extern enum mips_code_readable_setting m
/* ISA includes sync. */
#define ISA_HAS_SYNC ((mips_isa >= 2 || TARGET_MIPS3900) && !TARGET_MIPS16)
+#define GENERATE_SYNC (mips_llsc == LLSC_YES \
+ || (mips_llsc == LLSC_DEFAULT && ISA_HAS_SYNC))
/* ISA includes ll and sc. Note that this implies ISA_HAS_SYNC
because the expanders use both ISA_HAS_SYNC and ISA_HAS_LL_SC
instructions. */
#define ISA_HAS_LL_SC (mips_isa >= 2 && !TARGET_MIPS16)
+#define GENERATE_LL_SC (mips_llsc == LLSC_YES \
+ || (mips_llsc == LLSC_DEFAULT && ISA_HAS_LL_SC))
/* Add -G xx support. */
@@ -2905,12 +2919,13 @@ while (0)
and OP is the instruction that should be used to load %3 into a
register. */
#define MIPS_COMPARE_AND_SWAP(SUFFIX, OP) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\tbne\t%0,%2,2f\n" \
"\t" OP "\t%@,%3\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tsc" SUFFIX "\t%@,%1\n\t" \
+ "%-" \
+ "beq\t%@,%.,1b\n" \
"\tnop\n" \
"2:%]%>%)"
@@ -2921,11 +2936,12 @@ while (0)
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_OP(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%@,%0\n" \
"\t" INSN "\t%@,%@,%1\n" \
- "\tsc" SUFFIX "\t%@,%0\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tsc" SUFFIX "\t%@,%0\n\t" \
+ "%-" \
+ "beq\t%@,%.,1b\n" \
"\tnop%]%>%)"
/* Return an asm string that atomically:
@@ -2937,11 +2953,12 @@ while (0)
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_OLD_OP(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tsc" SUFFIX "\t%@,%1\n\t" \
+ "%-" \
+ "beq\t%@,%.,1b\n" \
"\tnop%]%>%)"
/* Return an asm string that atomically:
@@ -2953,11 +2970,12 @@ while (0)
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_NEW_OP(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tsc" SUFFIX "\t%@,%1\n\t" \
+ "%-" \
+ "beq\t%@,%.,1b\n" \
"\t" INSN "\t%0,%0,%2%]%>%)"
/* Return an asm string that atomically:
@@ -2968,12 +2986,13 @@ while (0)
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_NAND(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%@,%0\n" \
"\tnor\t%@,%@,%.\n" \
"\t" INSN "\t%@,%@,%1\n" \
- "\tsc" SUFFIX "\t%@,%0\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tsc" SUFFIX "\t%@,%0\n\t" \
+ "%-" \
+ "beq\t%@,%.,1b\n" \
"\tnop%]%>%)"
/* Return an asm string that atomically:
@@ -2986,12 +3005,13 @@ while (0)
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_OLD_NAND(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\tnor\t%@,%0,%.\n" \
"\t" INSN "\t%@,%@,%2\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tsc" SUFFIX "\t%@,%1\n\t" \
+ "%-" \
+ "beq\t%@,%.,1b\n" \
"\tnop%]%>%)"
/* Return an asm string that atomically:
@@ -3004,12 +3024,13 @@ while (0)
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_NEW_NAND(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\tnor\t%0,%0,%.\n" \
"\t" INSN "\t%@,%0,%2\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tsc" SUFFIX "\t%@,%1\n\t" \
+ "%-" \
+ "beq\t%@,%.,1b\n" \
"\t" INSN "\t%0,%0,%2%]%>%)"
/* Return an asm string that atomically:
@@ -3022,11 +3043,11 @@ while (0)
instructions. OP is the and instruction that should be used to
load %2 into a register. */
#define MIPS_SYNC_EXCHANGE(SUFFIX, OP) \
- "%(%<%[\n" \
+ "%(%<%[%|\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" OP "\t%@,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq\t%@,%.,1b\n" \
"\tnop\n" \
- "\tsync%]%>%)"
+ "\tsync\n\t%-%]%>%)"