aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/cris
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2012-07-16 03:18:23 +0000
committerHans-Peter Nilsson <hp@gcc.gnu.org>2012-07-16 03:18:23 +0000
commitdec4306fcbd361b4fa76736adb6864a45b5e7edb (patch)
tree3da01c0897396ffedb1b61b55133dc2a9f7c3389 /gcc/config/cris
parent24ddb79c2dbe77c7d4eb774dc4793cde6cd8a506 (diff)
downloadgcc-dec4306fcbd361b4fa76736adb6864a45b5e7edb.zip
gcc-dec4306fcbd361b4fa76736adb6864a45b5e7edb.tar.gz
gcc-dec4306fcbd361b4fa76736adb6864a45b5e7edb.tar.bz2
cris.c (cris_init_libfuncs): Handle initialization of library functions for basic atomic compare-and-swap.
* config/cris/cris.c (cris_init_libfuncs): Handle initialization of library functions for basic atomic compare-and-swap. * config/cris/cris.h (TARGET_ATOMICS_MAY_CALL_LIBFUNCS): New macro. * config/cris/cris.opt (munaligned-atomic-may-use-library): New option. * config/cris/sync.md ("atomic_fetch_<atomic_op_name><mode>") ("cris_atomic_fetch_<atomic_op_name><mode>_1") ("atomic_compare_and_swap<mode>") ("cris_atomic_compare_and_swap<mode>_1"): Make conditional on TARGET_ATOMICS_MAY_CALL_LIBFUNCS for sizes larger than byte. From-SVN: r189504
Diffstat (limited to 'gcc/config/cris')
-rw-r--r--gcc/config/cris/cris.c10
-rw-r--r--gcc/config/cris/cris.h5
-rw-r--r--gcc/config/cris/cris.opt4
-rw-r--r--gcc/config/cris/sync.md6
4 files changed, 22 insertions, 3 deletions
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 44e328b..71bb276 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -2761,6 +2761,16 @@ cris_init_libfuncs (void)
set_optab_libfunc (udiv_optab, SImode, "__Udiv");
set_optab_libfunc (smod_optab, SImode, "__Mod");
set_optab_libfunc (umod_optab, SImode, "__Umod");
+
+ /* Atomic data being unaligned is unfortunately a reality.
+ Deal with it. */
+ if (TARGET_ATOMICS_MAY_CALL_LIBFUNCS)
+ {
+ set_optab_libfunc (sync_compare_and_swap_optab, SImode,
+ "__cris_atcmpxchgr32");
+ set_optab_libfunc (sync_compare_and_swap_optab, HImode,
+ "__cris_atcmpxchgr16");
+ }
}
/* The INIT_EXPANDERS worker sets the per-function-data initializer and
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index b0bc57f..d5cf85e 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -316,6 +316,11 @@ extern int cris_cpu_version;
#define TARGET_TRAP_USING_BREAK8 \
(cris_trap_using_break8 == 2 ? TARGET_HAS_BREAK : cris_trap_using_break8)
+/* Call library functions by default for GNU/Linux. */
+#define TARGET_ATOMICS_MAY_CALL_LIBFUNCS \
+ (cris_atomics_calling_libfunc == 2 \
+ ? TARGET_LINUX : cris_atomics_calling_libfunc)
+
/* The < v10 atomics turn off interrupts, so they don't need alignment.
Incidentally, by default alignment is off there causing variables to
be default unaligned all over, so we'd have to make support
diff --git a/gcc/config/cris/cris.opt b/gcc/config/cris/cris.opt
index ebbddaa..d4433a7 100644
--- a/gcc/config/cris/cris.opt
+++ b/gcc/config/cris/cris.opt
@@ -183,6 +183,10 @@ mtrap-unaligned-atomic
Target Report Var(cris_trap_unaligned_atomic) Init(2)
Emit checks causing \"break 8\" instructions to execute when applying atomic builtins on misaligned memory
+munaligned-atomic-may-use-library
+Target Report Var(cris_atomics_calling_libfunc) Init(2)
+Handle atomic builtins that may be applied to unaligned data by calling library functions. Overrides -mtrap-unaligned-atomic.
+
; TARGET_SVINTO: Currently this just affects alignment. FIXME:
; Redundant with TARGET_ALIGN_BY_32, or put machine stuff here?
; This and the others below could just as well be variables and
diff --git a/gcc/config/cris/sync.md b/gcc/config/cris/sync.md
index b1dac81..1066db0 100644
--- a/gcc/config/cris/sync.md
+++ b/gcc/config/cris/sync.md
@@ -130,7 +130,7 @@
(set (match_operand:BWD 0 "register_operand" "=&r")
(match_dup 1))
(clobber (match_scratch:SI 3 "=&r"))]
- ""
+ "<MODE>mode == QImode || !TARGET_ATOMICS_MAY_CALL_LIBFUNCS"
{
/* Can't be too sure; better ICE if this happens. */
gcc_assert (!reg_overlap_mentioned_p (operands[2], operands[1]));
@@ -210,7 +210,7 @@
(match_operand 5)
(match_operand 6)
(match_operand 7)]
- ""
+ "<MODE>mode == QImode || !TARGET_ATOMICS_MAY_CALL_LIBFUNCS"
{
enum memmodel mmodel = (enum memmodel) INTVAL (operands[6]);
@@ -244,7 +244,7 @@
(match_dup 3)
(match_operand:BWD 4 "register_operand" "r")]
CRIS_UNSPEC_ATOMIC_SWAP_MEM))]
- ""
+ "<MODE>mode == QImode || !TARGET_ATOMICS_MAY_CALL_LIBFUNCS"
{
if (TARGET_V32)
return