aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 41a052b..72e2591 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5338,6 +5338,7 @@ static enum memmodel
get_memmodel (tree exp)
{
rtx op;
+ unsigned HOST_WIDE_INT val;
/* If the parameter is not a constant, it's a run time value so we'll just
convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking. */
@@ -5345,13 +5346,25 @@ get_memmodel (tree exp)
return MEMMODEL_SEQ_CST;
op = expand_normal (exp);
- if (INTVAL (op) < 0 || INTVAL (op) >= MEMMODEL_LAST)
+
+ val = INTVAL (op);
+ if (targetm.memmodel_check)
+ val = targetm.memmodel_check (val);
+ else if (val & ~MEMMODEL_MASK)
+ {
+ warning (OPT_Winvalid_memory_model,
+ "Unknown architecture specifier in memory model to builtin.");
+ return MEMMODEL_SEQ_CST;
+ }
+
+ if ((INTVAL(op) & MEMMODEL_MASK) >= MEMMODEL_LAST)
{
warning (OPT_Winvalid_memory_model,
"invalid memory model argument to builtin");
return MEMMODEL_SEQ_CST;
}
- return (enum memmodel) INTVAL (op);
+
+ return (enum memmodel) val;
}
/* Expand the __atomic_exchange intrinsic:
@@ -5366,7 +5379,7 @@ expand_builtin_atomic_exchange (enum machine_mode mode, tree exp, rtx target)
enum memmodel model;
model = get_memmodel (CALL_EXPR_ARG (exp, 2));
- if (model == MEMMODEL_CONSUME)
+ if ((model & MEMMODEL_MASK) == MEMMODEL_CONSUME)
{
error ("invalid memory model for %<__atomic_exchange%>");
return NULL_RTX;
@@ -5402,7 +5415,8 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp,
success = get_memmodel (CALL_EXPR_ARG (exp, 4));
failure = get_memmodel (CALL_EXPR_ARG (exp, 5));
- if (failure == MEMMODEL_RELEASE || failure == MEMMODEL_ACQ_REL)
+ if ((failure & MEMMODEL_MASK) == MEMMODEL_RELEASE
+ || (failure & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
error ("invalid failure memory model for %<__atomic_compare_exchange%>");
return NULL_RTX;
@@ -5453,8 +5467,8 @@ expand_builtin_atomic_load (enum machine_mode mode, tree exp, rtx target)
enum memmodel model;
model = get_memmodel (CALL_EXPR_ARG (exp, 1));
- if (model == MEMMODEL_RELEASE
- || model == MEMMODEL_ACQ_REL)
+ if ((model & MEMMODEL_MASK) == MEMMODEL_RELEASE
+ || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
error ("invalid memory model for %<__atomic_load%>");
return NULL_RTX;
@@ -5482,9 +5496,9 @@ expand_builtin_atomic_store (enum machine_mode mode, tree exp)
enum memmodel model;
model = get_memmodel (CALL_EXPR_ARG (exp, 2));
- if (model != MEMMODEL_RELAXED
- && model != MEMMODEL_SEQ_CST
- && model != MEMMODEL_RELEASE)
+ if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED
+ && (model & MEMMODEL_MASK) != MEMMODEL_SEQ_CST
+ && (model & MEMMODEL_MASK) != MEMMODEL_RELEASE)
{
error ("invalid memory model for %<__atomic_store%>");
return NULL_RTX;
@@ -5590,7 +5604,8 @@ expand_builtin_atomic_clear (tree exp)
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
model = get_memmodel (CALL_EXPR_ARG (exp, 1));
- if (model == MEMMODEL_ACQUIRE || model == MEMMODEL_ACQ_REL)
+ if ((model & MEMMODEL_MASK) == MEMMODEL_ACQUIRE
+ || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
error ("invalid memory model for %<__atomic_store%>");
return const0_rtx;