diff options
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 35 |
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; |