Replace the atomic intrinsics

Matching C11 in style
This commit is contained in:
gingerBill
2022-03-31 00:14:49 +01:00
parent 4eb4ae6305
commit 203382461b
6 changed files with 271 additions and 323 deletions

View File

@@ -379,6 +379,32 @@ bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call
}
}
bool check_atomic_memory_order_argument(CheckerContext *c, Ast *expr, String const &builtin_name, char const *extra_message = nullptr) {
Operand x = {};
check_expr_with_type_hint(c, &x, expr, t_atomic_memory_order);
if (x.mode == Addressing_Invalid) {
return false;
}
if (!are_types_identical(x.type, t_atomic_memory_order) || x.mode != Addressing_Constant) {
gbString str = type_to_string(x.type);
if (extra_message) {
error(x.expr, "Expected a constant Atomic_Memory_Order value for the %s of '%.*s', got %s", extra_message, LIT(builtin_name), str);
} else {
error(x.expr, "Expected a constant Atomic_Memory_Order value for '%.*s', got %s", LIT(builtin_name), str);
}
gb_string_free(str);
return false;
}
i64 value = exact_value_to_i64(x.value);
if (value < 0 || value >= OdinAtomicMemoryOrder_COUNT) {
error(x.expr, "Illegal Atomic_Memory_Order value, got %lld", cast(long long)value);
return false;
}
return true;
}
bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) {
ast_node(ce, CallExpr, call);
if (ce->inlining != ProcInlining_none) {
@@ -423,6 +449,11 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
// NOTE(bill): The first arg may be a Type, this will be checked case by case
break;
case BuiltinProc_atomic_thread_fence:
case BuiltinProc_atomic_signal_fence:
// NOTE(bill): first type will require a type hint
break;
case BuiltinProc_DIRECTIVE: {
ast_node(bd, BasicDirective, ce->proc);
String name = bd->name.string;
@@ -3198,10 +3229,12 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
break;
case BuiltinProc_atomic_fence:
case BuiltinProc_atomic_fence_acq:
case BuiltinProc_atomic_fence_rel:
case BuiltinProc_atomic_fence_acqrel:
case BuiltinProc_atomic_thread_fence:
case BuiltinProc_atomic_signal_fence:
if (!check_atomic_memory_order_argument(c, ce->args[0], builtin_name)) {
return false;
}
operand->mode = Addressing_NoValue;
break;
@@ -3210,9 +3243,6 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
case BuiltinProc_unaligned_store:
/*fallthrough*/
case BuiltinProc_atomic_store:
case BuiltinProc_atomic_store_rel:
case BuiltinProc_atomic_store_relaxed:
case BuiltinProc_atomic_store_unordered:
{
Type *elem = nullptr;
if (!is_type_normal_pointer(operand->type, &elem)) {
@@ -3228,14 +3258,32 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
break;
}
case BuiltinProc_atomic_store_explicit:
{
Type *elem = nullptr;
if (!is_type_normal_pointer(operand->type, &elem)) {
error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name));
return false;
}
Operand x = {};
check_expr_with_type_hint(c, &x, ce->args[1], elem);
check_assignment(c, &x, elem, builtin_name);
if (!check_atomic_memory_order_argument(c, ce->args[2], builtin_name)) {
return false;
}
operand->type = nullptr;
operand->mode = Addressing_NoValue;
break;
}
case BuiltinProc_volatile_load:
/*fallthrough*/
case BuiltinProc_unaligned_load:
/*fallthrough*/
case BuiltinProc_atomic_load:
case BuiltinProc_atomic_load_acq:
case BuiltinProc_atomic_load_relaxed:
case BuiltinProc_atomic_load_unordered:
{
Type *elem = nullptr;
if (!is_type_normal_pointer(operand->type, &elem)) {
@@ -3247,41 +3295,30 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
break;
}
case BuiltinProc_atomic_load_explicit:
{
Type *elem = nullptr;
if (!is_type_normal_pointer(operand->type, &elem)) {
error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name));
return false;
}
if (!check_atomic_memory_order_argument(c, ce->args[1], builtin_name)) {
return false;
}
operand->type = elem;
operand->mode = Addressing_Value;
break;
}
case BuiltinProc_atomic_add:
case BuiltinProc_atomic_add_acq:
case BuiltinProc_atomic_add_rel:
case BuiltinProc_atomic_add_acqrel:
case BuiltinProc_atomic_add_relaxed:
case BuiltinProc_atomic_sub:
case BuiltinProc_atomic_sub_acq:
case BuiltinProc_atomic_sub_rel:
case BuiltinProc_atomic_sub_acqrel:
case BuiltinProc_atomic_sub_relaxed:
case BuiltinProc_atomic_and:
case BuiltinProc_atomic_and_acq:
case BuiltinProc_atomic_and_rel:
case BuiltinProc_atomic_and_acqrel:
case BuiltinProc_atomic_and_relaxed:
case BuiltinProc_atomic_nand:
case BuiltinProc_atomic_nand_acq:
case BuiltinProc_atomic_nand_rel:
case BuiltinProc_atomic_nand_acqrel:
case BuiltinProc_atomic_nand_relaxed:
case BuiltinProc_atomic_or:
case BuiltinProc_atomic_or_acq:
case BuiltinProc_atomic_or_rel:
case BuiltinProc_atomic_or_acqrel:
case BuiltinProc_atomic_or_relaxed:
case BuiltinProc_atomic_xor:
case BuiltinProc_atomic_xor_acq:
case BuiltinProc_atomic_xor_rel:
case BuiltinProc_atomic_xor_acqrel:
case BuiltinProc_atomic_xor_relaxed:
case BuiltinProc_atomic_xchg:
case BuiltinProc_atomic_xchg_acq:
case BuiltinProc_atomic_xchg_rel:
case BuiltinProc_atomic_xchg_acqrel:
case BuiltinProc_atomic_xchg_relaxed:
case BuiltinProc_atomic_exchange:
{
Type *elem = nullptr;
if (!is_type_normal_pointer(operand->type, &elem)) {
@@ -3297,25 +3334,35 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
break;
}
case BuiltinProc_atomic_cxchg:
case BuiltinProc_atomic_cxchg_acq:
case BuiltinProc_atomic_cxchg_rel:
case BuiltinProc_atomic_cxchg_acqrel:
case BuiltinProc_atomic_cxchg_relaxed:
case BuiltinProc_atomic_cxchg_failrelaxed:
case BuiltinProc_atomic_cxchg_failacq:
case BuiltinProc_atomic_cxchg_acq_failrelaxed:
case BuiltinProc_atomic_cxchg_acqrel_failrelaxed:
case BuiltinProc_atomic_add_explicit:
case BuiltinProc_atomic_sub_explicit:
case BuiltinProc_atomic_and_explicit:
case BuiltinProc_atomic_nand_explicit:
case BuiltinProc_atomic_or_explicit:
case BuiltinProc_atomic_xor_explicit:
case BuiltinProc_atomic_exchange_explicit:
{
Type *elem = nullptr;
if (!is_type_normal_pointer(operand->type, &elem)) {
error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name));
return false;
}
Operand x = {};
check_expr_with_type_hint(c, &x, ce->args[1], elem);
check_assignment(c, &x, elem, builtin_name);
case BuiltinProc_atomic_cxchgweak:
case BuiltinProc_atomic_cxchgweak_acq:
case BuiltinProc_atomic_cxchgweak_rel:
case BuiltinProc_atomic_cxchgweak_acqrel:
case BuiltinProc_atomic_cxchgweak_relaxed:
case BuiltinProc_atomic_cxchgweak_failrelaxed:
case BuiltinProc_atomic_cxchgweak_failacq:
case BuiltinProc_atomic_cxchgweak_acq_failrelaxed:
case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed:
if (!check_atomic_memory_order_argument(c, ce->args[2], builtin_name)) {
return false;
}
operand->type = elem;
operand->mode = Addressing_Value;
break;
}
case BuiltinProc_atomic_compare_exchange_strong:
case BuiltinProc_atomic_compare_exchange_weak:
{
Type *elem = nullptr;
if (!is_type_normal_pointer(operand->type, &elem)) {
@@ -3333,7 +3380,33 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
operand->type = elem;
break;
}
break;
case BuiltinProc_atomic_compare_exchange_strong_explicit:
case BuiltinProc_atomic_compare_exchange_weak_explicit:
{
Type *elem = nullptr;
if (!is_type_normal_pointer(operand->type, &elem)) {
error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name));
return false;
}
Operand x = {};
Operand y = {};
check_expr_with_type_hint(c, &x, ce->args[1], elem);
check_expr_with_type_hint(c, &y, ce->args[2], elem);
check_assignment(c, &x, elem, builtin_name);
check_assignment(c, &y, elem, builtin_name);
if (!check_atomic_memory_order_argument(c, ce->args[3], builtin_name, "success ordering")) {
return false;
}
if (!check_atomic_memory_order_argument(c, ce->args[4], builtin_name, "failure ordering")) {
return false;
}
operand->mode = Addressing_OptionalOk;
operand->type = elem;
break;
}
case BuiltinProc_fixed_point_mul:
case BuiltinProc_fixed_point_div:

View File

@@ -829,15 +829,16 @@ struct GlobalEnumValue {
i64 value;
};
Slice<Entity *> add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count) {
Slice<Entity *> add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count, Type **enum_type_ = nullptr) {
Scope *scope = create_scope(nullptr, builtin_pkg->scope);
Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved);
Entity *entity = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved);
Type *enum_type = alloc_type_enum();
Type *named_type = alloc_type_named(type_name, enum_type, e);
Type *named_type = alloc_type_named(type_name, enum_type, entity);
set_base_type(named_type, enum_type);
enum_type->Enum.base_type = t_int;
enum_type->Enum.scope = scope;
entity->type = named_type;
auto fields = array_make<Entity *>(permanent_allocator(), value_count);
for (isize i = 0; i < value_count; i++) {
@@ -858,6 +859,9 @@ Slice<Entity *> add_global_enum_type(String const &type_name, GlobalEnumValue *v
enum_type->Enum.min_value = &enum_type->Enum.fields[enum_type->Enum.min_value_index]->Constant.value;
enum_type->Enum.max_value = &enum_type->Enum.fields[enum_type->Enum.max_value_index]->Constant.value;
if (enum_type_) *enum_type_ = named_type;
return slice_from_array(fields);
}
void add_global_enum_constant(Slice<Entity *> const &fields, char const *name, i64 value) {
@@ -986,6 +990,21 @@ void init_universal(void) {
add_global_enum_constant(fields, "ODIN_ERROR_POS_STYLE", build_context.ODIN_ERROR_POS_STYLE);
}
{
GlobalEnumValue values[OdinAtomicMemoryOrder_COUNT] = {
{"relaxed", OdinAtomicMemoryOrder_relaxed},
{"consume", OdinAtomicMemoryOrder_consume},
{"acquire", OdinAtomicMemoryOrder_acquire},
{"release", OdinAtomicMemoryOrder_release},
{"acq_rel", OdinAtomicMemoryOrder_acq_rel},
{"seq_cst", OdinAtomicMemoryOrder_seq_cst},
};
add_global_enum_type(str_lit("Atomic_Memory_Order"), values, gb_count_of(values), &t_atomic_memory_order);
GB_ASSERT(t_atomic_memory_order->kind == Type_Named);
scope_insert(intrinsics_pkg->scope, t_atomic_memory_order->Named.type_name);
}
add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG);
add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT);

View File

@@ -86,77 +86,30 @@ enum BuiltinProcId {
BuiltinProc_prefetch_write_instruction,
BuiltinProc_prefetch_write_data,
BuiltinProc_atomic_fence,
BuiltinProc_atomic_fence_acq,
BuiltinProc_atomic_fence_rel,
BuiltinProc_atomic_fence_acqrel,
BuiltinProc_atomic_thread_fence,
BuiltinProc_atomic_signal_fence,
BuiltinProc_atomic_store,
BuiltinProc_atomic_store_rel,
BuiltinProc_atomic_store_relaxed,
BuiltinProc_atomic_store_unordered,
BuiltinProc_atomic_store_explicit,
BuiltinProc_atomic_load,
BuiltinProc_atomic_load_acq,
BuiltinProc_atomic_load_relaxed,
BuiltinProc_atomic_load_unordered,
BuiltinProc_atomic_load_explicit,
BuiltinProc_atomic_add,
BuiltinProc_atomic_add_acq,
BuiltinProc_atomic_add_rel,
BuiltinProc_atomic_add_acqrel,
BuiltinProc_atomic_add_relaxed,
BuiltinProc_atomic_add_explicit,
BuiltinProc_atomic_sub,
BuiltinProc_atomic_sub_acq,
BuiltinProc_atomic_sub_rel,
BuiltinProc_atomic_sub_acqrel,
BuiltinProc_atomic_sub_relaxed,
BuiltinProc_atomic_sub_explicit,
BuiltinProc_atomic_and,
BuiltinProc_atomic_and_acq,
BuiltinProc_atomic_and_rel,
BuiltinProc_atomic_and_acqrel,
BuiltinProc_atomic_and_relaxed,
BuiltinProc_atomic_and_explicit,
BuiltinProc_atomic_nand,
BuiltinProc_atomic_nand_acq,
BuiltinProc_atomic_nand_rel,
BuiltinProc_atomic_nand_acqrel,
BuiltinProc_atomic_nand_relaxed,
BuiltinProc_atomic_nand_explicit,
BuiltinProc_atomic_or,
BuiltinProc_atomic_or_acq,
BuiltinProc_atomic_or_rel,
BuiltinProc_atomic_or_acqrel,
BuiltinProc_atomic_or_relaxed,
BuiltinProc_atomic_or_explicit,
BuiltinProc_atomic_xor,
BuiltinProc_atomic_xor_acq,
BuiltinProc_atomic_xor_rel,
BuiltinProc_atomic_xor_acqrel,
BuiltinProc_atomic_xor_relaxed,
BuiltinProc_atomic_xchg,
BuiltinProc_atomic_xchg_acq,
BuiltinProc_atomic_xchg_rel,
BuiltinProc_atomic_xchg_acqrel,
BuiltinProc_atomic_xchg_relaxed,
BuiltinProc_atomic_cxchg,
BuiltinProc_atomic_cxchg_acq,
BuiltinProc_atomic_cxchg_rel,
BuiltinProc_atomic_cxchg_acqrel,
BuiltinProc_atomic_cxchg_relaxed,
BuiltinProc_atomic_cxchg_failrelaxed,
BuiltinProc_atomic_cxchg_failacq,
BuiltinProc_atomic_cxchg_acq_failrelaxed,
BuiltinProc_atomic_cxchg_acqrel_failrelaxed,
BuiltinProc_atomic_cxchgweak,
BuiltinProc_atomic_cxchgweak_acq,
BuiltinProc_atomic_cxchgweak_rel,
BuiltinProc_atomic_cxchgweak_acqrel,
BuiltinProc_atomic_cxchgweak_relaxed,
BuiltinProc_atomic_cxchgweak_failrelaxed,
BuiltinProc_atomic_cxchgweak_failacq,
BuiltinProc_atomic_cxchgweak_acq_failrelaxed,
BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed,
BuiltinProc_atomic_xor_explicit,
BuiltinProc_atomic_exchange,
BuiltinProc_atomic_exchange_explicit,
BuiltinProc_atomic_compare_exchange_strong,
BuiltinProc_atomic_compare_exchange_strong_explicit,
BuiltinProc_atomic_compare_exchange_weak,
BuiltinProc_atomic_compare_exchange_weak_explicit,
BuiltinProc_fixed_point_mul,
BuiltinProc_fixed_point_div,
@@ -352,78 +305,30 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("prefetch_write_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_fence"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_fence_acq"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_fence_rel"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_fence_acqrel"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_store_rel"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_store_relaxed"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_store_unordered"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_load_acq"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_load_relaxed"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_load_unordered"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_add_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_add_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_add_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_add_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_sub_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_sub_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_sub_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_sub_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_and_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_and_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_and_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_and_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_nand"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_nand_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_nand_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_nand_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_nand_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_or_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_or_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_or_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_or_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xor"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xor_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xor_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xor_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xor_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xchg"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xchg_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xchg_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xchg_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xchg_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg_acq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg_rel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg_acqrel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg_relaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg_failacq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg_acq_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchg_acqrel_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak_acq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak_rel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak_acqrel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak_relaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak_failacq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak_acq_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_cxchgweak_acqrel_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_thread_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_signal_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_store_explicit"), 3, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_load_explicit"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_add_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_sub_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_and_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_nand"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_nand_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_or_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xor"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_xor_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_exchange"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_exchange_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_compare_exchange_strong"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_compare_exchange_strong_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_compare_exchange_weak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_compare_exchange_weak_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("fixed_point_mul"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("fixed_point_div"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},

View File

@@ -1606,36 +1606,26 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
}
case BuiltinProc_atomic_fence:
LLVMBuildFence(p->builder, LLVMAtomicOrderingSequentiallyConsistent, false, "");
// TODO(bill): Which is correct?
case BuiltinProc_atomic_thread_fence:
LLVMBuildFence(p->builder, llvm_atomic_ordering_from_odin(ce->args[0]), false, "");
return {};
case BuiltinProc_atomic_fence_acq:
LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquire, false, "");
return {};
case BuiltinProc_atomic_fence_rel:
LLVMBuildFence(p->builder, LLVMAtomicOrderingRelease, false, "");
return {};
case BuiltinProc_atomic_fence_acqrel:
LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquireRelease, false, "");
case BuiltinProc_atomic_signal_fence:
LLVMBuildFence(p->builder, llvm_atomic_ordering_from_odin(ce->args[0]), true, "");
return {};
case BuiltinProc_volatile_store:
case BuiltinProc_atomic_store:
case BuiltinProc_atomic_store_rel:
case BuiltinProc_atomic_store_relaxed:
case BuiltinProc_atomic_store_unordered: {
case BuiltinProc_atomic_store_explicit: {
lbValue dst = lb_build_expr(p, ce->args[0]);
lbValue val = lb_build_expr(p, ce->args[1]);
val = lb_emit_conv(p, val, type_deref(dst.type));
LLVMValueRef instr = LLVMBuildStore(p->builder, val.value, dst.value);
switch (id) {
case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break;
case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
case BuiltinProc_atomic_store_rel: LLVMSetOrdering(instr, LLVMAtomicOrderingRelease); break;
case BuiltinProc_atomic_store_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break;
case BuiltinProc_atomic_store_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break;
case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break;
case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
case BuiltinProc_atomic_store_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[2])); break;
}
LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
@@ -1645,18 +1635,14 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
case BuiltinProc_volatile_load:
case BuiltinProc_atomic_load:
case BuiltinProc_atomic_load_acq:
case BuiltinProc_atomic_load_relaxed:
case BuiltinProc_atomic_load_unordered: {
case BuiltinProc_atomic_load_explicit: {
lbValue dst = lb_build_expr(p, ce->args[0]);
LLVMValueRef instr = LLVMBuildLoad(p->builder, dst.value, "");
switch (id) {
case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break;
case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
case BuiltinProc_atomic_load_acq: LLVMSetOrdering(instr, LLVMAtomicOrderingAcquire); break;
case BuiltinProc_atomic_load_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break;
case BuiltinProc_atomic_load_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break;
case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break;
case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
case BuiltinProc_atomic_load_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[1])); break;
}
LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
@@ -1686,40 +1672,19 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
}
case BuiltinProc_atomic_add:
case BuiltinProc_atomic_add_acq:
case BuiltinProc_atomic_add_rel:
case BuiltinProc_atomic_add_acqrel:
case BuiltinProc_atomic_add_relaxed:
case BuiltinProc_atomic_sub:
case BuiltinProc_atomic_sub_acq:
case BuiltinProc_atomic_sub_rel:
case BuiltinProc_atomic_sub_acqrel:
case BuiltinProc_atomic_sub_relaxed:
case BuiltinProc_atomic_and:
case BuiltinProc_atomic_and_acq:
case BuiltinProc_atomic_and_rel:
case BuiltinProc_atomic_and_acqrel:
case BuiltinProc_atomic_and_relaxed:
case BuiltinProc_atomic_nand:
case BuiltinProc_atomic_nand_acq:
case BuiltinProc_atomic_nand_rel:
case BuiltinProc_atomic_nand_acqrel:
case BuiltinProc_atomic_nand_relaxed:
case BuiltinProc_atomic_or:
case BuiltinProc_atomic_or_acq:
case BuiltinProc_atomic_or_rel:
case BuiltinProc_atomic_or_acqrel:
case BuiltinProc_atomic_or_relaxed:
case BuiltinProc_atomic_xor:
case BuiltinProc_atomic_xor_acq:
case BuiltinProc_atomic_xor_rel:
case BuiltinProc_atomic_xor_acqrel:
case BuiltinProc_atomic_xor_relaxed:
case BuiltinProc_atomic_xchg:
case BuiltinProc_atomic_xchg_acq:
case BuiltinProc_atomic_xchg_rel:
case BuiltinProc_atomic_xchg_acqrel:
case BuiltinProc_atomic_xchg_relaxed: {
case BuiltinProc_atomic_exchange:
case BuiltinProc_atomic_add_explicit:
case BuiltinProc_atomic_sub_explicit:
case BuiltinProc_atomic_and_explicit:
case BuiltinProc_atomic_nand_explicit:
case BuiltinProc_atomic_or_explicit:
case BuiltinProc_atomic_xor_explicit:
case BuiltinProc_atomic_exchange_explicit: {
lbValue dst = lb_build_expr(p, ce->args[0]);
lbValue val = lb_build_expr(p, ce->args[1]);
val = lb_emit_conv(p, val, type_deref(dst.type));
@@ -1728,41 +1693,20 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
LLVMAtomicOrdering ordering = {};
switch (id) {
case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_add_acq: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquire; break;
case BuiltinProc_atomic_add_rel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingRelease; break;
case BuiltinProc_atomic_add_acqrel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquireRelease; break;
case BuiltinProc_atomic_add_relaxed: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingMonotonic; break;
case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_sub_acq: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquire; break;
case BuiltinProc_atomic_sub_rel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingRelease; break;
case BuiltinProc_atomic_sub_acqrel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquireRelease; break;
case BuiltinProc_atomic_sub_relaxed: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingMonotonic; break;
case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_and_acq: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquire; break;
case BuiltinProc_atomic_and_rel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingRelease; break;
case BuiltinProc_atomic_and_acqrel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquireRelease; break;
case BuiltinProc_atomic_and_relaxed: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingMonotonic; break;
case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_nand_acq: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquire; break;
case BuiltinProc_atomic_nand_rel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingRelease; break;
case BuiltinProc_atomic_nand_acqrel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquireRelease; break;
case BuiltinProc_atomic_nand_relaxed: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingMonotonic; break;
case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_or_acq: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquire; break;
case BuiltinProc_atomic_or_rel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingRelease; break;
case BuiltinProc_atomic_or_acqrel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquireRelease; break;
case BuiltinProc_atomic_or_relaxed: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingMonotonic; break;
case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_xor_acq: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquire; break;
case BuiltinProc_atomic_xor_rel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingRelease; break;
case BuiltinProc_atomic_xor_acqrel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquireRelease; break;
case BuiltinProc_atomic_xor_relaxed: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingMonotonic; break;
case BuiltinProc_atomic_xchg: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_xchg_acq: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquire; break;
case BuiltinProc_atomic_xchg_rel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingRelease; break;
case BuiltinProc_atomic_xchg_acqrel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquireRelease; break;
case BuiltinProc_atomic_xchg_relaxed: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingMonotonic; break;
case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_exchange: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
case BuiltinProc_atomic_add_explicit: op = LLVMAtomicRMWBinOpAdd; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
case BuiltinProc_atomic_sub_explicit: op = LLVMAtomicRMWBinOpSub; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
case BuiltinProc_atomic_and_explicit: op = LLVMAtomicRMWBinOpAnd; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
case BuiltinProc_atomic_nand_explicit: op = LLVMAtomicRMWBinOpNand; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
case BuiltinProc_atomic_or_explicit: op = LLVMAtomicRMWBinOpOr; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
case BuiltinProc_atomic_xor_explicit: op = LLVMAtomicRMWBinOpXor; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
case BuiltinProc_atomic_exchange_explicit: op = LLVMAtomicRMWBinOpXchg; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
}
lbValue res = {};
@@ -1771,24 +1715,10 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
return res;
}
case BuiltinProc_atomic_cxchg:
case BuiltinProc_atomic_cxchg_acq:
case BuiltinProc_atomic_cxchg_rel:
case BuiltinProc_atomic_cxchg_acqrel:
case BuiltinProc_atomic_cxchg_relaxed:
case BuiltinProc_atomic_cxchg_failrelaxed:
case BuiltinProc_atomic_cxchg_failacq:
case BuiltinProc_atomic_cxchg_acq_failrelaxed:
case BuiltinProc_atomic_cxchg_acqrel_failrelaxed:
case BuiltinProc_atomic_cxchgweak:
case BuiltinProc_atomic_cxchgweak_acq:
case BuiltinProc_atomic_cxchgweak_rel:
case BuiltinProc_atomic_cxchgweak_acqrel:
case BuiltinProc_atomic_cxchgweak_relaxed:
case BuiltinProc_atomic_cxchgweak_failrelaxed:
case BuiltinProc_atomic_cxchgweak_failacq:
case BuiltinProc_atomic_cxchgweak_acq_failrelaxed:
case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: {
case BuiltinProc_atomic_compare_exchange_strong:
case BuiltinProc_atomic_compare_exchange_weak:
case BuiltinProc_atomic_compare_exchange_strong_explicit:
case BuiltinProc_atomic_compare_exchange_weak_explicit: {
lbValue address = lb_build_expr(p, ce->args[0]);
Type *elem = type_deref(address.type);
lbValue old_value = lb_build_expr(p, ce->args[1]);
@@ -1801,24 +1731,10 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
LLVMBool weak = false;
switch (id) {
case BuiltinProc_atomic_cxchg: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
case BuiltinProc_atomic_cxchg_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
case BuiltinProc_atomic_cxchg_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
case BuiltinProc_atomic_cxchg_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
case BuiltinProc_atomic_cxchg_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
case BuiltinProc_atomic_cxchg_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
case BuiltinProc_atomic_cxchg_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = false; break;
case BuiltinProc_atomic_cxchg_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
case BuiltinProc_atomic_cxchgweak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
case BuiltinProc_atomic_cxchgweak_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
case BuiltinProc_atomic_cxchgweak_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
case BuiltinProc_atomic_cxchgweak_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
case BuiltinProc_atomic_cxchgweak_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
case BuiltinProc_atomic_cxchgweak_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
case BuiltinProc_atomic_cxchgweak_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = true; break;
case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
case BuiltinProc_atomic_compare_exchange_strong: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
case BuiltinProc_atomic_compare_exchange_weak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
case BuiltinProc_atomic_compare_exchange_strong_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = false; break;
case BuiltinProc_atomic_compare_exchange_weak_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = true; break;
}
// TODO(bill): Figure out how to make it weak

View File

@@ -2005,3 +2005,25 @@ lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) {
}
LLVMAtomicOrdering llvm_atomic_ordering_from_odin(ExactValue const &value) {
GB_ASSERT(value.kind == ExactValue_Integer);
i64 v = exact_value_to_i64(value);
switch (v) {
case OdinAtomicMemoryOrder_relaxed: return LLVMAtomicOrderingUnordered;
case OdinAtomicMemoryOrder_consume: return LLVMAtomicOrderingMonotonic;
case OdinAtomicMemoryOrder_acquire: return LLVMAtomicOrderingAcquire;
case OdinAtomicMemoryOrder_release: return LLVMAtomicOrderingRelease;
case OdinAtomicMemoryOrder_acq_rel: return LLVMAtomicOrderingAcquireRelease;
case OdinAtomicMemoryOrder_seq_cst: return LLVMAtomicOrderingSequentiallyConsistent;
}
GB_PANIC("Unknown atomic ordering");
return LLVMAtomicOrderingSequentiallyConsistent;
}
LLVMAtomicOrdering llvm_atomic_ordering_from_odin(Ast *expr) {
ExactValue value = type_and_value_of_expr(expr).value;
return llvm_atomic_ordering_from_odin(value);
}

View File

@@ -692,6 +692,19 @@ gb_global Type *t_objc_id = nullptr;
gb_global Type *t_objc_SEL = nullptr;
gb_global Type *t_objc_Class = nullptr;
enum OdinAtomicMemoryOrder : i32 {
OdinAtomicMemoryOrder_relaxed = 0,
OdinAtomicMemoryOrder_consume = 1,
OdinAtomicMemoryOrder_acquire = 2,
OdinAtomicMemoryOrder_release = 3,
OdinAtomicMemoryOrder_acq_rel = 4,
OdinAtomicMemoryOrder_seq_cst = 5,
OdinAtomicMemoryOrder_COUNT,
};
gb_global Type *t_atomic_memory_order = nullptr;
gb_global RecursiveMutex g_type_mutex;