mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Add atomic_fetch_exchange builtin.
This commit is contained in:
@@ -2663,6 +2663,24 @@ INLINE bool type_is_pointer_vector(Type *type)
|
||||
return type->type_kind == TYPE_VECTOR && type->array.base->canonical->type_kind == TYPE_POINTER;
|
||||
}
|
||||
|
||||
INLINE bool type_is_atomic(Type *type_flat)
|
||||
{
|
||||
switch (type_flat->type_kind)
|
||||
{
|
||||
case ALL_UNSIGNED_INTS:
|
||||
case ALL_SIGNED_INTS:
|
||||
case ALL_FLOATS:
|
||||
case TYPE_ENUM:
|
||||
case TYPE_FAULTTYPE:
|
||||
case TYPE_ANYFAULT:
|
||||
case TYPE_TYPEID:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return type_size(type_flat) <= type_size(type_iptr);
|
||||
}
|
||||
|
||||
INLINE bool type_is_pointer(Type *type)
|
||||
{
|
||||
DECL_TYPE_KIND_REAL(kind, type);
|
||||
|
||||
@@ -841,6 +841,7 @@ typedef enum
|
||||
BUILTIN_ABS,
|
||||
BUILTIN_ATOMIC_LOAD,
|
||||
BUILTIN_ATOMIC_STORE,
|
||||
BUILTIN_ATOMIC_FETCH_EXCHANGE,
|
||||
BUILTIN_ATOMIC_FETCH_ADD,
|
||||
BUILTIN_ATOMIC_FETCH_SUB,
|
||||
BUILTIN_ATOMIC_FETCH_AND,
|
||||
|
||||
@@ -192,6 +192,9 @@ INLINE void llvm_emit_atomic_fetch(GenContext *c, BuiltinFunction func, BEValue
|
||||
static LLVMAtomicRMWBinOp LLVMAtomicRMWBinOpUDecWrap = LLVMAtomicRMWBinOpFMin + 2;
|
||||
switch (func)
|
||||
{
|
||||
case BUILTIN_ATOMIC_FETCH_EXCHANGE:
|
||||
op = LLVMAtomicRMWBinOpXchg;
|
||||
break;
|
||||
case BUILTIN_ATOMIC_FETCH_ADD:
|
||||
op = is_float ? LLVMAtomicRMWBinOpFAdd : LLVMAtomicRMWBinOpAdd;
|
||||
break;
|
||||
@@ -815,6 +818,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
|
||||
case BUILTIN_ATOMIC_FETCH_MIN:
|
||||
case BUILTIN_ATOMIC_FETCH_SUB:
|
||||
case BUILTIN_ATOMIC_FETCH_DEC_WRAP:
|
||||
case BUILTIN_ATOMIC_FETCH_EXCHANGE:
|
||||
llvm_emit_atomic_fetch(c, func, result_value, expr);
|
||||
return;
|
||||
case BUILTIN_ATOMIC_LOAD:
|
||||
|
||||
@@ -779,6 +779,29 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
rtype = args[1]->type;
|
||||
break;
|
||||
}
|
||||
case BUILTIN_ATOMIC_FETCH_EXCHANGE:
|
||||
{
|
||||
assert(arg_count == 5);
|
||||
if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_POINTER }, 1)) return false;
|
||||
Type *original = type_flatten(args[0]->type);
|
||||
if (original != type_voidptr)
|
||||
{
|
||||
if (!cast_implicit(context, args[1], original->pointer)) return false;
|
||||
}
|
||||
Type *val = type_flatten(args[1]->type);
|
||||
if (!type_is_atomic(val)) RETURN_SEMA_ERROR(args[1], "%s exceeds pointer size.", val);
|
||||
if (!expr_is_const(args[2])) RETURN_SEMA_ERROR(args[2], "'is_volatile' must be a compile time constant.");
|
||||
if (!expr_is_const(args[3])) RETURN_SEMA_ERROR(args[3], "Ordering must be a compile time constant.");
|
||||
if (!is_valid_atomicity(args[3])) return false;
|
||||
switch (args[3]->const_expr.ixx.i.low)
|
||||
{
|
||||
case ATOMIC_UNORDERED:
|
||||
RETURN_SEMA_ERROR(args[3], "'unordered' is not valid ordering.");
|
||||
}
|
||||
if (!sema_check_alignment_expression(context, args[4])) return false;
|
||||
rtype = args[1]->type;
|
||||
break;
|
||||
}
|
||||
case BUILTIN_ATOMIC_FETCH_ADD:
|
||||
case BUILTIN_ATOMIC_FETCH_SUB:
|
||||
case BUILTIN_ATOMIC_FETCH_MAX:
|
||||
@@ -939,6 +962,7 @@ static inline int builtin_expected_args(BuiltinFunction func)
|
||||
case BUILTIN_GATHER:
|
||||
case BUILTIN_SCATTER:
|
||||
return 4;
|
||||
case BUILTIN_ATOMIC_FETCH_EXCHANGE:
|
||||
case BUILTIN_ATOMIC_FETCH_ADD:
|
||||
case BUILTIN_ATOMIC_FETCH_INC_WRAP:
|
||||
case BUILTIN_ATOMIC_FETCH_NAND:
|
||||
|
||||
@@ -200,6 +200,7 @@ void symtab_init(uint32_t capacity)
|
||||
builtin_list[BUILTIN_ATOMIC_LOAD] = KW_DEF("atomic_load");
|
||||
builtin_list[BUILTIN_ATOMIC_STORE] = KW_DEF("atomic_store");
|
||||
builtin_list[BUILTIN_ATOMIC_FETCH_ADD] = KW_DEF("atomic_fetch_add");
|
||||
builtin_list[BUILTIN_ATOMIC_FETCH_EXCHANGE] = KW_DEF("atomic_fetch_exchange");
|
||||
builtin_list[BUILTIN_ATOMIC_FETCH_SUB] = KW_DEF("atomic_fetch_sub");
|
||||
builtin_list[BUILTIN_ATOMIC_FETCH_MAX] = KW_DEF("atomic_fetch_max");
|
||||
builtin_list[BUILTIN_ATOMIC_FETCH_MIN] = KW_DEF("atomic_fetch_min");
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.647"
|
||||
#define COMPILER_VERSION "0.4.648"
|
||||
Reference in New Issue
Block a user