| ... | ... | @@ -347,6 +347,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) { |
| 347 | 347 | return IrInstructionIdEmbedFile; |
| 348 | 348 | } |
| 349 | 349 | |
| 350 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchg *) { |
| 351 | return IrInstructionIdCmpxchg; |
| 352 | } |
| 353 | |
| 354 | static constexpr IrInstructionId ir_instruction_id(IrInstructionFence *) { |
| 355 | return IrInstructionIdFence; |
| 356 | } |
| 357 | |
| 350 | 358 | template<typename T> |
| 351 | 359 | static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) { |
| 352 | 360 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -1357,6 +1365,54 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode |
| 1357 | 1365 | return &instruction->base; |
| 1358 | 1366 | } |
| 1359 | 1367 | |
| 1368 | static IrInstruction *ir_build_cmpxchg(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr, |
| 1369 | IrInstruction *cmp_value, IrInstruction *new_value, IrInstruction *success_order_value, IrInstruction *failure_order_value, |
| 1370 | AtomicOrder success_order, AtomicOrder failure_order) |
| 1371 | { |
| 1372 | IrInstructionCmpxchg *instruction = ir_build_instruction<IrInstructionCmpxchg>(irb, scope, source_node); |
| 1373 | instruction->ptr = ptr; |
| 1374 | instruction->cmp_value = cmp_value; |
| 1375 | instruction->new_value = new_value; |
| 1376 | instruction->success_order_value = success_order_value; |
| 1377 | instruction->failure_order_value = failure_order_value; |
| 1378 | instruction->success_order = success_order; |
| 1379 | instruction->failure_order = failure_order; |
| 1380 | |
| 1381 | ir_ref_instruction(ptr); |
| 1382 | ir_ref_instruction(cmp_value); |
| 1383 | ir_ref_instruction(new_value); |
| 1384 | ir_ref_instruction(success_order_value); |
| 1385 | ir_ref_instruction(failure_order_value); |
| 1386 | |
| 1387 | return &instruction->base; |
| 1388 | } |
| 1389 | |
| 1390 | static IrInstruction *ir_build_cmpxchg_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *ptr, |
| 1391 | IrInstruction *cmp_value, IrInstruction *new_value, IrInstruction *success_order_value, IrInstruction *failure_order_value, |
| 1392 | AtomicOrder success_order, AtomicOrder failure_order) |
| 1393 | { |
| 1394 | IrInstruction *new_instruction = ir_build_cmpxchg(irb, old_instruction->scope, old_instruction->source_node, |
| 1395 | ptr, cmp_value, new_value, success_order_value, failure_order_value, success_order, failure_order); |
| 1396 | ir_link_new_instruction(new_instruction, old_instruction); |
| 1397 | return new_instruction; |
| 1398 | } |
| 1399 | |
| 1400 | static IrInstruction *ir_build_fence(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *order_value, AtomicOrder order) { |
| 1401 | IrInstructionFence *instruction = ir_build_instruction<IrInstructionFence>(irb, scope, source_node); |
| 1402 | instruction->order_value = order_value; |
| 1403 | instruction->order = order; |
| 1404 | |
| 1405 | ir_ref_instruction(order_value); |
| 1406 | |
| 1407 | return &instruction->base; |
| 1408 | } |
| 1409 | |
| 1410 | static IrInstruction *ir_build_fence_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *order_value, AtomicOrder order) { |
| 1411 | IrInstruction *new_instruction = ir_build_fence(irb, old_instruction->scope, old_instruction->source_node, order_value, order); |
| 1412 | ir_link_new_instruction(new_instruction, old_instruction); |
| 1413 | return new_instruction; |
| 1414 | } |
| 1415 | |
| 1360 | 1416 | static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, |
| 1361 | 1417 | bool gen_error_defers, bool gen_maybe_defers) |
| 1362 | 1418 | { |
| ... | ... | @@ -2096,6 +2152,46 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 2096 | 2152 | |
| 2097 | 2153 | return ir_build_embed_file(irb, scope, node, arg0_value); |
| 2098 | 2154 | } |
| 2155 | case BuiltinFnIdCmpExchange: |
| 2156 | { |
| 2157 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 2158 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 2159 | if (arg0_value == irb->codegen->invalid_instruction) |
| 2160 | return arg0_value; |
| 2161 | |
| 2162 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 2163 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); |
| 2164 | if (arg1_value == irb->codegen->invalid_instruction) |
| 2165 | return arg1_value; |
| 2166 | |
| 2167 | AstNode *arg2_node = node->data.fn_call_expr.params.at(2); |
| 2168 | IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); |
| 2169 | if (arg2_value == irb->codegen->invalid_instruction) |
| 2170 | return arg2_value; |
| 2171 | |
| 2172 | AstNode *arg3_node = node->data.fn_call_expr.params.at(3); |
| 2173 | IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); |
| 2174 | if (arg3_value == irb->codegen->invalid_instruction) |
| 2175 | return arg3_value; |
| 2176 | |
| 2177 | AstNode *arg4_node = node->data.fn_call_expr.params.at(4); |
| 2178 | IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); |
| 2179 | if (arg4_value == irb->codegen->invalid_instruction) |
| 2180 | return arg4_value; |
| 2181 | |
| 2182 | return ir_build_cmpxchg(irb, scope, node, arg0_value, arg1_value, |
| 2183 | arg2_value, arg3_value, arg4_value, |
| 2184 | AtomicOrderUnordered, AtomicOrderUnordered); |
| 2185 | } |
| 2186 | case BuiltinFnIdFence: |
| 2187 | { |
| 2188 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 2189 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 2190 | if (arg0_value == irb->codegen->invalid_instruction) |
| 2191 | return arg0_value; |
| 2192 | |
| 2193 | return ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); |
| 2194 | } |
| 2099 | 2195 | case BuiltinFnIdMemcpy: |
| 2100 | 2196 | case BuiltinFnIdMemset: |
| 2101 | 2197 | case BuiltinFnIdAlignof: |
| ... | ... | @@ -2107,8 +2203,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 2107 | 2203 | case BuiltinFnIdBreakpoint: |
| 2108 | 2204 | case BuiltinFnIdReturnAddress: |
| 2109 | 2205 | case BuiltinFnIdFrameAddress: |
| 2110 | | case BuiltinFnIdCmpExchange: |
| 2111 | | case BuiltinFnIdFence: |
| 2112 | 2206 | case BuiltinFnIdDivExact: |
| 2113 | 2207 | case BuiltinFnIdTruncate: |
| 2114 | 2208 | case BuiltinFnIdIntType: |
| ... | ... | @@ -3470,6 +3564,12 @@ static bool is_slice(TypeTableEntry *type) { |
| 3470 | 3564 | return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice; |
| 3471 | 3565 | } |
| 3472 | 3566 | |
| 3567 | static bool is_container(TypeTableEntry *type) { |
| 3568 | return type->id == TypeTableEntryIdStruct || |
| 3569 | type->id == TypeTableEntryIdEnum || |
| 3570 | type->id == TypeTableEntryIdUnion; |
| 3571 | } |
| 3572 | |
| 3473 | 3573 | static bool is_u8(TypeTableEntry *type) { |
| 3474 | 3574 | return type->id == TypeTableEntryIdInt && |
| 3475 | 3575 | !type->data.integral.is_signed && type->data.integral.bit_count == 8; |
| ... | ... | @@ -4085,6 +4185,22 @@ static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { |
| 4085 | 4185 | return true; |
| 4086 | 4186 | } |
| 4087 | 4187 | |
| 4188 | static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) { |
| 4189 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 4190 | return false; |
| 4191 | |
| 4192 | IrInstruction *casted_value = ir_get_casted_value(ira, value, ira->codegen->builtin_types.entry_atomic_order_enum); |
| 4193 | if (casted_value->type_entry->id == TypeTableEntryIdInvalid) |
| 4194 | return false; |
| 4195 | |
| 4196 | ConstExprValue *const_val = ir_resolve_const(ira, casted_value); |
| 4197 | if (!const_val) |
| 4198 | return false; |
| 4199 | |
| 4200 | *out = (AtomicOrder)const_val->data.x_enum.tag; |
| 4201 | return true; |
| 4202 | } |
| 4203 | |
| 4088 | 4204 | static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 4089 | 4205 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 4090 | 4206 | return nullptr; |
| ... | ... | @@ -5689,15 +5805,23 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5689 | 5805 | if (container_ptr->type_entry->id == TypeTableEntryIdInvalid) |
| 5690 | 5806 | return ira->codegen->builtin_types.entry_invalid; |
| 5691 | 5807 | |
| 5692 | | assert(container_ptr->type_entry->id == TypeTableEntryIdPointer); |
| 5693 | | TypeTableEntry *container_type = container_ptr->type_entry->data.pointer.child_type; |
| 5808 | TypeTableEntry *container_type; |
| 5809 | if (container_ptr->type_entry->id == TypeTableEntryIdPointer) { |
| 5810 | container_type = container_ptr->type_entry->data.pointer.child_type; |
| 5811 | } else if (container_ptr->type_entry->id == TypeTableEntryIdMetaType) { |
| 5812 | container_type = container_ptr->type_entry; |
| 5813 | } else { |
| 5814 | zig_unreachable(); |
| 5815 | } |
| 5694 | 5816 | |
| 5817 | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 5695 | 5818 | Buf *field_name = field_ptr_instruction->field_name; |
| 5696 | 5819 | AstNode *source_node = field_ptr_instruction->base.source_node; |
| 5697 | 5820 | |
| 5698 | 5821 | if (container_type->id == TypeTableEntryIdInvalid) { |
| 5699 | 5822 | return container_type; |
| 5700 | 5823 | } else if (is_container_ref(container_type)) { |
| 5824 | assert(container_ptr->type_entry->id == TypeTableEntryIdPointer); |
| 5701 | 5825 | return ir_analyze_container_field_ptr(ira, field_name, field_ptr_instruction, container_ptr, container_type); |
| 5702 | 5826 | } else if (container_type->id == TypeTableEntryIdArray) { |
| 5703 | 5827 | if (buf_eql_str(field_name, "len")) { |
| ... | ... | @@ -5717,26 +5841,43 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5717 | 5841 | ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr); |
| 5718 | 5842 | if (!container_ptr_val) |
| 5719 | 5843 | return ira->codegen->builtin_types.entry_invalid; |
| 5720 | | ConstExprValue *child_val = const_ptr_pointee(container_ptr_val); |
| 5721 | | TypeTableEntry *child_type = child_val->data.x_type; |
| 5844 | |
| 5845 | TypeTableEntry *child_type; |
| 5846 | if (container_ptr->type_entry->id == TypeTableEntryIdMetaType) { |
| 5847 | TypeTableEntry *ptr_type = container_ptr_val->data.x_type; |
| 5848 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 5849 | child_type = ptr_type->data.pointer.child_type; |
| 5850 | } else if (container_ptr->type_entry->id == TypeTableEntryIdPointer) { |
| 5851 | ConstExprValue *child_val = const_ptr_pointee(container_ptr_val); |
| 5852 | child_type = child_val->data.x_type; |
| 5853 | } else { |
| 5854 | zig_unreachable(); |
| 5855 | } |
| 5722 | 5856 | |
| 5723 | 5857 | if (child_type->id == TypeTableEntryIdInvalid) { |
| 5724 | 5858 | return ira->codegen->builtin_types.entry_invalid; |
| 5725 | | } else if (child_type->id == TypeTableEntryIdEnum) { |
| 5726 | | zig_panic("TODO enum type field"); |
| 5727 | | } else if (child_type->id == TypeTableEntryIdStruct) { |
| 5859 | } else if (is_container(child_type)) { |
| 5860 | if (child_type->id == TypeTableEntryIdEnum) { |
| 5861 | TypeEnumField *field = find_enum_type_field(child_type, field_name); |
| 5862 | if (field) { |
| 5863 | if (field->type_entry->id == TypeTableEntryIdVoid) { |
| 5864 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, create_const_enum_tag(field->value), |
| 5865 | child_type, depends_on_compile_var, ConstPtrSpecialNone); |
| 5866 | } else { |
| 5867 | zig_panic("TODO enum tag type"); |
| 5868 | } |
| 5869 | } |
| 5870 | } |
| 5728 | 5871 | ScopeDecls *container_scope = get_container_scope(child_type); |
| 5729 | 5872 | auto entry = container_scope->decl_table.maybe_get(field_name); |
| 5730 | 5873 | Tld *tld = entry ? entry->value : nullptr; |
| 5731 | 5874 | if (tld) { |
| 5732 | | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 5733 | 5875 | return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld, depends_on_compile_var); |
| 5734 | | } else { |
| 5735 | | add_node_error(ira->codegen, source_node, |
| 5736 | | buf_sprintf("container '%s' has no member called '%s'", |
| 5737 | | buf_ptr(&child_type->name), buf_ptr(field_name))); |
| 5738 | | return ira->codegen->builtin_types.entry_invalid; |
| 5739 | 5876 | } |
| 5877 | ir_add_error(ira, &field_ptr_instruction->base, |
| 5878 | buf_sprintf("container '%s' has no member called '%s'", |
| 5879 | buf_ptr(&child_type->name), buf_ptr(field_name))); |
| 5880 | return ira->codegen->builtin_types.entry_invalid; |
| 5740 | 5881 | } else if (child_type->id == TypeTableEntryIdPureError) { |
| 5741 | 5882 | auto err_table_entry = ira->codegen->error_table.maybe_get(field_name); |
| 5742 | 5883 | if (err_table_entry) { |
| ... | ... | @@ -5744,7 +5885,6 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5744 | 5885 | const_val->special = ConstValSpecialStatic; |
| 5745 | 5886 | const_val->data.x_pure_err = err_table_entry->value; |
| 5746 | 5887 | |
| 5747 | | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 5748 | 5888 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, const_val, |
| 5749 | 5889 | child_type, depends_on_compile_var, ConstPtrSpecialNone); |
| 5750 | 5890 | } |
| ... | ... | @@ -5760,6 +5900,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5760 | 5900 | return ira->codegen->builtin_types.entry_invalid; |
| 5761 | 5901 | } |
| 5762 | 5902 | } else if (container_type->id == TypeTableEntryIdNamespace) { |
| 5903 | assert(container_ptr->type_entry->id == TypeTableEntryIdPointer); |
| 5763 | 5904 | ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr); |
| 5764 | 5905 | if (!container_ptr_val) |
| 5765 | 5906 | return ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -5769,7 +5910,6 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5769 | 5910 | |
| 5770 | 5911 | ImportTableEntry *namespace_import = namespace_val->data.x_import; |
| 5771 | 5912 | |
| 5772 | | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 5773 | 5913 | Tld *tld = find_decl(&namespace_import->decls_scope->base, field_name); |
| 5774 | 5914 | if (!tld) { |
| 5775 | 5915 | // we must now resolve all the use decls |
| ... | ... | @@ -7184,10 +7324,10 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr |
| 7184 | 7324 | int err; |
| 7185 | 7325 | if ((err = os_fetch_file_path(&file_path, &file_contents))) { |
| 7186 | 7326 | if (err == ErrorFileNotFound) { |
| 7187 | | ir_add_error(ira, &instruction->base, buf_sprintf("unable to find '%s'", buf_ptr(&file_path))); |
| 7327 | ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path))); |
| 7188 | 7328 | return ira->codegen->builtin_types.entry_invalid; |
| 7189 | 7329 | } else { |
| 7190 | | ir_add_error(ira, &instruction->base, buf_sprintf("unable to open '%s': %s", buf_ptr(&file_path), err_str(err))); |
| 7330 | ir_add_error(ira, instruction->name, buf_sprintf("unable to open '%s': %s", buf_ptr(&file_path), err_str(err))); |
| 7191 | 7331 | return ira->codegen->builtin_types.entry_invalid; |
| 7192 | 7332 | } |
| 7193 | 7333 | } |
| ... | ... | @@ -7197,11 +7337,94 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr |
| 7197 | 7337 | |
| 7198 | 7338 | bool depends_on_compile_var = true; |
| 7199 | 7339 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var); |
| 7200 | | init_const_str_lit(out_val,&file_contents); |
| 7340 | init_const_str_lit(out_val, &file_contents); |
| 7201 | 7341 | |
| 7202 | 7342 | return get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(&file_contents)); |
| 7203 | 7343 | } |
| 7204 | 7344 | |
| 7345 | static TypeTableEntry *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchg *instruction) { |
| 7346 | IrInstruction *ptr = instruction->ptr->other; |
| 7347 | if (ptr->type_entry->id == TypeTableEntryIdInvalid) |
| 7348 | return ira->codegen->builtin_types.entry_invalid; |
| 7349 | |
| 7350 | IrInstruction *cmp_value = instruction->cmp_value->other; |
| 7351 | if (cmp_value->type_entry->id == TypeTableEntryIdInvalid) |
| 7352 | return ira->codegen->builtin_types.entry_invalid; |
| 7353 | |
| 7354 | IrInstruction *new_value = instruction->new_value->other; |
| 7355 | if (new_value->type_entry->id == TypeTableEntryIdInvalid) |
| 7356 | return ira->codegen->builtin_types.entry_invalid; |
| 7357 | |
| 7358 | IrInstruction *success_order_value = instruction->success_order_value->other; |
| 7359 | if (success_order_value->type_entry->id == TypeTableEntryIdInvalid) |
| 7360 | return ira->codegen->builtin_types.entry_invalid; |
| 7361 | |
| 7362 | AtomicOrder success_order; |
| 7363 | if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) |
| 7364 | return ira->codegen->builtin_types.entry_invalid; |
| 7365 | |
| 7366 | IrInstruction *failure_order_value = instruction->failure_order_value->other; |
| 7367 | if (failure_order_value->type_entry->id == TypeTableEntryIdInvalid) |
| 7368 | return ira->codegen->builtin_types.entry_invalid; |
| 7369 | |
| 7370 | AtomicOrder failure_order; |
| 7371 | if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) |
| 7372 | return ira->codegen->builtin_types.entry_invalid; |
| 7373 | |
| 7374 | if (ptr->type_entry->id != TypeTableEntryIdPointer) { |
| 7375 | ir_add_error(ira, instruction->ptr, |
| 7376 | buf_sprintf("expected pointer argument, found '%s'", buf_ptr(&ptr->type_entry->name))); |
| 7377 | return ira->codegen->builtin_types.entry_invalid; |
| 7378 | } |
| 7379 | |
| 7380 | TypeTableEntry *child_type = ptr->type_entry->data.pointer.child_type; |
| 7381 | |
| 7382 | IrInstruction *casted_cmp_value = ir_get_casted_value(ira, cmp_value, child_type); |
| 7383 | if (casted_cmp_value->type_entry->id == TypeTableEntryIdInvalid) |
| 7384 | return ira->codegen->builtin_types.entry_invalid; |
| 7385 | |
| 7386 | IrInstruction *casted_new_value = ir_get_casted_value(ira, new_value, child_type); |
| 7387 | if (casted_new_value->type_entry->id == TypeTableEntryIdInvalid) |
| 7388 | return ira->codegen->builtin_types.entry_invalid; |
| 7389 | |
| 7390 | if (success_order < AtomicOrderMonotonic) { |
| 7391 | ir_add_error(ira, success_order_value, |
| 7392 | buf_sprintf("success atomic ordering must be Monotonic or stricter")); |
| 7393 | return ira->codegen->builtin_types.entry_invalid; |
| 7394 | } |
| 7395 | if (failure_order < AtomicOrderMonotonic) { |
| 7396 | ir_add_error(ira, failure_order_value, |
| 7397 | buf_sprintf("failure atomic ordering must be Monotonic or stricter")); |
| 7398 | return ira->codegen->builtin_types.entry_invalid; |
| 7399 | } |
| 7400 | if (failure_order > success_order) { |
| 7401 | ir_add_error(ira, failure_order_value, |
| 7402 | buf_sprintf("failure atomic ordering must be no stricter than success")); |
| 7403 | return ira->codegen->builtin_types.entry_invalid; |
| 7404 | } |
| 7405 | if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { |
| 7406 | ir_add_error(ira, failure_order_value, |
| 7407 | buf_sprintf("failure atomic ordering must not be Release or AcqRel")); |
| 7408 | return ira->codegen->builtin_types.entry_invalid; |
| 7409 | } |
| 7410 | |
| 7411 | ir_build_cmpxchg_from(&ira->new_irb, &instruction->base, ptr, casted_cmp_value, casted_new_value, |
| 7412 | success_order_value, failure_order_value, success_order, failure_order); |
| 7413 | return ira->codegen->builtin_types.entry_bool; |
| 7414 | } |
| 7415 | |
| 7416 | static TypeTableEntry *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { |
| 7417 | IrInstruction *order_value = instruction->order_value->other; |
| 7418 | if (order_value->type_entry->id == TypeTableEntryIdInvalid) |
| 7419 | return ira->codegen->builtin_types.entry_invalid; |
| 7420 | |
| 7421 | AtomicOrder order; |
| 7422 | if (!ir_resolve_atomic_order(ira, order_value, &order)) |
| 7423 | return ira->codegen->builtin_types.entry_invalid; |
| 7424 | |
| 7425 | ir_build_fence_from(&ira->new_irb, &instruction->base, order_value, order); |
| 7426 | return ira->codegen->builtin_types.entry_void; |
| 7427 | } |
| 7205 | 7428 | |
| 7206 | 7429 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 7207 | 7430 | switch (instruction->id) { |
| ... | ... | @@ -7305,6 +7528,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 7305 | 7528 | return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); |
| 7306 | 7529 | case IrInstructionIdEmbedFile: |
| 7307 | 7530 | return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction); |
| 7531 | case IrInstructionIdCmpxchg: |
| 7532 | return ir_analyze_instruction_cmpxchg(ira, (IrInstructionCmpxchg *)instruction); |
| 7533 | case IrInstructionIdFence: |
| 7534 | return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); |
| 7308 | 7535 | case IrInstructionIdCast: |
| 7309 | 7536 | case IrInstructionIdStructFieldPtr: |
| 7310 | 7537 | case IrInstructionIdEnumFieldPtr: |
| ... | ... | @@ -7404,6 +7631,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7404 | 7631 | case IrInstructionIdCInclude: |
| 7405 | 7632 | case IrInstructionIdCDefine: |
| 7406 | 7633 | case IrInstructionIdCUndef: |
| 7634 | case IrInstructionIdCmpxchg: |
| 7635 | case IrInstructionIdFence: |
| 7407 | 7636 | return true; |
| 7408 | 7637 | case IrInstructionIdPhi: |
| 7409 | 7638 | case IrInstructionIdUnOp: |
| ... | ... | @@ -7453,102 +7682,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7453 | 7682 | // TODO port over all this commented out code into new IR way of doing things |
| 7454 | 7683 | |
| 7455 | 7684 | |
| 7456 | | //static TypeTableEntry *analyze_cmpxchg(CodeGen *g, ImportTableEntry *import, |
| 7457 | | // BlockContext *context, AstNode *node) |
| 7458 | | //{ |
| 7459 | | // assert(node->type == NodeTypeFnCallExpr); |
| 7460 | | // |
| 7461 | | // AstNode **ptr_arg = &node->data.fn_call_expr.params.at(0); |
| 7462 | | // AstNode **cmp_arg = &node->data.fn_call_expr.params.at(1); |
| 7463 | | // AstNode **new_arg = &node->data.fn_call_expr.params.at(2); |
| 7464 | | // AstNode **success_order_arg = &node->data.fn_call_expr.params.at(3); |
| 7465 | | // AstNode **failure_order_arg = &node->data.fn_call_expr.params.at(4); |
| 7466 | | // |
| 7467 | | // TypeTableEntry *ptr_type = analyze_expression(g, import, context, nullptr, *ptr_arg); |
| 7468 | | // if (ptr_type->id == TypeTableEntryIdInvalid) { |
| 7469 | | // return g->builtin_types.entry_invalid; |
| 7470 | | // } else if (ptr_type->id != TypeTableEntryIdPointer) { |
| 7471 | | // add_node_error(g, *ptr_arg, |
| 7472 | | // buf_sprintf("expected pointer argument, found '%s'", buf_ptr(&ptr_type->name))); |
| 7473 | | // return g->builtin_types.entry_invalid; |
| 7474 | | // } |
| 7475 | | // |
| 7476 | | // TypeTableEntry *child_type = ptr_type->data.pointer.child_type; |
| 7477 | | // TypeTableEntry *cmp_type = analyze_expression(g, import, context, child_type, *cmp_arg); |
| 7478 | | // TypeTableEntry *new_type = analyze_expression(g, import, context, child_type, *new_arg); |
| 7479 | | // |
| 7480 | | // TypeTableEntry *success_order_type = analyze_expression(g, import, context, |
| 7481 | | // g->builtin_types.entry_atomic_order_enum, *success_order_arg); |
| 7482 | | // TypeTableEntry *failure_order_type = analyze_expression(g, import, context, |
| 7483 | | // g->builtin_types.entry_atomic_order_enum, *failure_order_arg); |
| 7484 | | // |
| 7485 | | // if (cmp_type->id == TypeTableEntryIdInvalid || |
| 7486 | | // new_type->id == TypeTableEntryIdInvalid || |
| 7487 | | // success_order_type->id == TypeTableEntryIdInvalid || |
| 7488 | | // failure_order_type->id == TypeTableEntryIdInvalid) |
| 7489 | | // { |
| 7490 | | // return g->builtin_types.entry_invalid; |
| 7491 | | // } |
| 7492 | | // |
| 7493 | | // ConstExprValue *success_order_val = &get_resolved_expr(*success_order_arg)->const_val; |
| 7494 | | // ConstExprValue *failure_order_val = &get_resolved_expr(*failure_order_arg)->const_val; |
| 7495 | | // if (!success_order_val->ok) { |
| 7496 | | // add_node_error(g, *success_order_arg, buf_sprintf("unable to evaluate constant expression")); |
| 7497 | | // return g->builtin_types.entry_invalid; |
| 7498 | | // } else if (!failure_order_val->ok) { |
| 7499 | | // add_node_error(g, *failure_order_arg, buf_sprintf("unable to evaluate constant expression")); |
| 7500 | | // return g->builtin_types.entry_invalid; |
| 7501 | | // } |
| 7502 | | // |
| 7503 | | // if (success_order_val->data.x_enum.tag < AtomicOrderMonotonic) { |
| 7504 | | // add_node_error(g, *success_order_arg, |
| 7505 | | // buf_sprintf("success atomic ordering must be Monotonic or stricter")); |
| 7506 | | // return g->builtin_types.entry_invalid; |
| 7507 | | // } |
| 7508 | | // if (failure_order_val->data.x_enum.tag < AtomicOrderMonotonic) { |
| 7509 | | // add_node_error(g, *failure_order_arg, |
| 7510 | | // buf_sprintf("failure atomic ordering must be Monotonic or stricter")); |
| 7511 | | // return g->builtin_types.entry_invalid; |
| 7512 | | // } |
| 7513 | | // if (failure_order_val->data.x_enum.tag > success_order_val->data.x_enum.tag) { |
| 7514 | | // add_node_error(g, *failure_order_arg, |
| 7515 | | // buf_sprintf("failure atomic ordering must be no stricter than success")); |
| 7516 | | // return g->builtin_types.entry_invalid; |
| 7517 | | // } |
| 7518 | | // if (failure_order_val->data.x_enum.tag == AtomicOrderRelease || |
| 7519 | | // failure_order_val->data.x_enum.tag == AtomicOrderAcqRel) |
| 7520 | | // { |
| 7521 | | // add_node_error(g, *failure_order_arg, |
| 7522 | | // buf_sprintf("failure atomic ordering must not be Release or AcqRel")); |
| 7523 | | // return g->builtin_types.entry_invalid; |
| 7524 | | // } |
| 7525 | | // |
| 7526 | | // return g->builtin_types.entry_bool; |
| 7527 | | //} |
| 7528 | | // |
| 7529 | | //static TypeTableEntry *analyze_fence(CodeGen *g, ImportTableEntry *import, |
| 7530 | | // BlockContext *context, AstNode *node) |
| 7531 | | //{ |
| 7532 | | // assert(node->type == NodeTypeFnCallExpr); |
| 7533 | | // |
| 7534 | | // AstNode **atomic_order_arg = &node->data.fn_call_expr.params.at(0); |
| 7535 | | // TypeTableEntry *atomic_order_type = analyze_expression(g, import, context, |
| 7536 | | // g->builtin_types.entry_atomic_order_enum, *atomic_order_arg); |
| 7537 | | // |
| 7538 | | // if (atomic_order_type->id == TypeTableEntryIdInvalid) { |
| 7539 | | // return g->builtin_types.entry_invalid; |
| 7540 | | // } |
| 7541 | | // |
| 7542 | | // ConstExprValue *atomic_order_val = &get_resolved_expr(*atomic_order_arg)->const_val; |
| 7543 | | // |
| 7544 | | // if (!atomic_order_val->ok) { |
| 7545 | | // add_node_error(g, *atomic_order_arg, buf_sprintf("unable to evaluate constant expression")); |
| 7546 | | // return g->builtin_types.entry_invalid; |
| 7547 | | // } |
| 7548 | | // |
| 7549 | | // return g->builtin_types.entry_void; |
| 7550 | | //} |
| 7551 | | // |
| 7552 | 7685 | //static TypeTableEntry *analyze_div_exact(CodeGen *g, ImportTableEntry *import, |
| 7553 | 7686 | // BlockContext *context, AstNode *node) |
| 7554 | 7687 | //{ |
| ... | ... | @@ -7780,8 +7913,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7780 | 7913 | // return g->builtin_types.entry_invalid; |
| 7781 | 7914 | // } |
| 7782 | 7915 | // } |
| 7783 | | // case BuiltinFnIdImport: |
| 7784 | | // return analyze_import(g, import, context, node); |
| 7785 | 7916 | // case BuiltinFnIdBreakpoint: |
| 7786 | 7917 | // mark_impure_fn(g, context, node); |
| 7787 | 7918 | // return g->builtin_types.entry_void; |
| ... | ... | @@ -7789,20 +7920,12 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7789 | 7920 | // case BuiltinFnIdFrameAddress: |
| 7790 | 7921 | // mark_impure_fn(g, context, node); |
| 7791 | 7922 | // return builtin_fn->return_type; |
| 7792 | | // case BuiltinFnIdCmpExchange: |
| 7793 | | // return analyze_cmpxchg(g, import, context, node); |
| 7794 | | // case BuiltinFnIdFence: |
| 7795 | | // return analyze_fence(g, import, context, node); |
| 7796 | 7923 | // case BuiltinFnIdDivExact: |
| 7797 | 7924 | // return analyze_div_exact(g, import, context, node); |
| 7798 | 7925 | // case BuiltinFnIdTruncate: |
| 7799 | 7926 | // return analyze_truncate(g, import, context, node); |
| 7800 | 7927 | // case BuiltinFnIdIntType: |
| 7801 | 7928 | // return analyze_int_type(g, import, context, node); |
| 7802 | | // case BuiltinFnIdSetFnTest: |
| 7803 | | // return analyze_set_fn_test(g, import, context, node); |
| 7804 | | // case BuiltinFnIdSetFnNoInline: |
| 7805 | | // return analyze_set_fn_no_inline(g, import, context, node); |
| 7806 | 7929 | // } |
| 7807 | 7930 | // zig_unreachable(); |
| 7808 | 7931 | //} |
| ... | ... | @@ -7881,68 +8004,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7881 | 8004 | // } |
| 7882 | 8005 | // zig_unreachable(); |
| 7883 | 8006 | //} |
| 7884 | | //static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 7885 | | // AstNode *field_access_node, AstNode *value_node, TypeTableEntry *enum_type, Buf *field_name, |
| 7886 | | // AstNode *out_node) |
| 7887 | | //{ |
| 7888 | | // assert(field_access_node->type == NodeTypeFieldAccessExpr); |
| 7889 | | // |
| 7890 | | // TypeEnumField *type_enum_field = find_enum_type_field(enum_type, field_name); |
| 7891 | | // if (type_enum_field->type_entry->id == TypeTableEntryIdInvalid) { |
| 7892 | | // return g->builtin_types.entry_invalid; |
| 7893 | | // } |
| 7894 | | // |
| 7895 | | // field_access_node->data.field_access_expr.type_enum_field = type_enum_field; |
| 7896 | | // |
| 7897 | | // if (type_enum_field) { |
| 7898 | | // if (value_node) { |
| 7899 | | // AstNode **value_node_ptr = value_node->parent_field; |
| 7900 | | // TypeTableEntry *value_type = analyze_expression(g, import, context, |
| 7901 | | // type_enum_field->type_entry, value_node); |
| 7902 | | // |
| 7903 | | // if (value_type->id == TypeTableEntryIdInvalid) { |
| 7904 | | // return g->builtin_types.entry_invalid; |
| 7905 | | // } |
| 7906 | | // |
| 7907 | | // StructValExprCodeGen *codegen = &field_access_node->data.field_access_expr.resolved_struct_val_expr; |
| 7908 | | // codegen->type_entry = enum_type; |
| 7909 | | // codegen->source_node = field_access_node; |
| 7910 | | // |
| 7911 | | // ConstExprValue *value_const_val = &get_resolved_expr(*value_node_ptr)->const_val; |
| 7912 | | // if (value_const_val->ok) { |
| 7913 | | // ConstExprValue *const_val = &get_resolved_expr(out_node)->const_val; |
| 7914 | | // const_val->ok = true; |
| 7915 | | // const_val->data.x_enum.tag = type_enum_field->value; |
| 7916 | | // const_val->data.x_enum.payload = value_const_val; |
| 7917 | | // } else { |
| 7918 | | // if (context->fn_entry) { |
| 7919 | | // context->fn_entry->struct_val_expr_alloca_list.append(codegen); |
| 7920 | | // } else { |
| 7921 | | // add_node_error(g, *value_node_ptr, buf_sprintf("unable to evaluate constant expression")); |
| 7922 | | // return g->builtin_types.entry_invalid; |
| 7923 | | // } |
| 7924 | | // } |
| 7925 | | // } else if (type_enum_field->type_entry->id != TypeTableEntryIdVoid) { |
| 7926 | | // add_node_error(g, field_access_node, |
| 7927 | | // buf_sprintf("enum value '%s.%s' requires parameter of type '%s'", |
| 7928 | | // buf_ptr(&enum_type->name), |
| 7929 | | // buf_ptr(field_name), |
| 7930 | | // buf_ptr(&type_enum_field->type_entry->name))); |
| 7931 | | // } else { |
| 7932 | | // Expr *expr = get_resolved_expr(out_node); |
| 7933 | | // expr->const_val.ok = true; |
| 7934 | | // expr->const_val.data.x_enum.tag = type_enum_field->value; |
| 7935 | | // expr->const_val.data.x_enum.payload = nullptr; |
| 7936 | | // } |
| 7937 | | // } else { |
| 7938 | | // add_node_error(g, field_access_node, |
| 7939 | | // buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), |
| 7940 | | // buf_ptr(&enum_type->name))); |
| 7941 | | // } |
| 7942 | | // return enum_type; |
| 7943 | | //} |
| 7944 | | // |
| 7945 | | // |
| 7946 | 8007 | //static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 7947 | 8008 | // AstNode *node) |
| 7948 | 8009 | //{ |
| ... | ... | @@ -8182,34 +8243,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 8182 | 8243 | // |
| 8183 | 8244 | |
| 8184 | 8245 | |
| 8185 | | //static LLVMValueRef gen_cmp_exchange(CodeGen *g, AstNode *node) { |
| 8186 | | // assert(node->type == NodeTypeFnCallExpr); |
| 8187 | | // |
| 8188 | | // AstNode *ptr_arg = node->data.fn_call_expr.params.at(0); |
| 8189 | | // AstNode *cmp_arg = node->data.fn_call_expr.params.at(1); |
| 8190 | | // AstNode *new_arg = node->data.fn_call_expr.params.at(2); |
| 8191 | | // AstNode *success_order_arg = node->data.fn_call_expr.params.at(3); |
| 8192 | | // AstNode *failure_order_arg = node->data.fn_call_expr.params.at(4); |
| 8193 | | // |
| 8194 | | // LLVMValueRef ptr_val = gen_expr(g, ptr_arg); |
| 8195 | | // LLVMValueRef cmp_val = gen_expr(g, cmp_arg); |
| 8196 | | // LLVMValueRef new_val = gen_expr(g, new_arg); |
| 8197 | | // |
| 8198 | | // ConstExprValue *success_order_val = &get_resolved_expr(success_order_arg)->const_val; |
| 8199 | | // ConstExprValue *failure_order_val = &get_resolved_expr(failure_order_arg)->const_val; |
| 8200 | | // |
| 8201 | | // assert(success_order_val->ok); |
| 8202 | | // assert(failure_order_val->ok); |
| 8203 | | // |
| 8204 | | // LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering((AtomicOrder)success_order_val->data.x_enum.tag); |
| 8205 | | // LLVMAtomicOrdering failure_order = to_LLVMAtomicOrdering((AtomicOrder)failure_order_val->data.x_enum.tag); |
| 8206 | | // |
| 8207 | | // LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val, |
| 8208 | | // success_order, failure_order); |
| 8209 | | // |
| 8210 | | // return LLVMBuildExtractValue(g->builder, result_val, 1, ""); |
| 8211 | | //} |
| 8212 | | // |
| 8213 | 8246 | //static LLVMValueRef gen_div_exact(CodeGen *g, AstNode *node) { |
| 8214 | 8247 | // assert(node->type == NodeTypeFnCallExpr); |
| 8215 | 8248 | // |
| ... | ... | @@ -8269,9 +8302,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 8269 | 8302 | // switch (builtin_fn->id) { |
| 8270 | 8303 | // case BuiltinFnIdInvalid: |
| 8271 | 8304 | // case BuiltinFnIdTypeof: |
| 8272 | | // case BuiltinFnIdImport: |
| 8273 | | // case BuiltinFnIdCImport: |
| 8274 | | // case BuiltinFnIdCompileErr: |
| 8275 | 8305 | // case BuiltinFnIdIntType: |
| 8276 | 8306 | // zig_unreachable(); |
| 8277 | 8307 | // case BuiltinFnIdAddWithOverflow: |
| ... | ... | @@ -8585,25 +8615,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 8585 | 8615 | // } |
| 8586 | 8616 | //} |
| 8587 | 8617 | // |
| 8588 | | // |
| 8589 | | // |
| 8590 | | //static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) { |
| 8591 | | // assert(node->type == NodeTypeBinOpExpr); |
| 8592 | | // |
| 8593 | | // AstNode *lhs_node = node->data.bin_op_expr.op1; |
| 8594 | | // |
| 8595 | | // TypeTableEntry *op1_type; |
| 8596 | | // |
| 8597 | | // LLVMValueRef target_ref = gen_lvalue(g, node, lhs_node, &op1_type); |
| 8598 | | // |
| 8599 | | // TypeTableEntry *op2_type = get_expr_type(node->data.bin_op_expr.op2); |
| 8600 | | // |
| 8601 | | // LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); |
| 8602 | | // |
| 8603 | | // gen_assign_raw(g, node, node->data.bin_op_expr.bin_op, target_ref, value, op1_type, op2_type); |
| 8604 | | // return nullptr; |
| 8605 | | //} |
| 8606 | | // |
| 8607 | 8618 | //static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) { |
| 8608 | 8619 | // assert(node->type == NodeTypeUnwrapErrorExpr); |
| 8609 | 8620 | // |
| ... | ... | @@ -8894,71 +8905,3 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 8894 | 8905 | // gen_var_debug_decl(g, variable); |
| 8895 | 8906 | // return nullptr; |
| 8896 | 8907 | //} |
| 8897 | | // |
| 8898 | | //static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node, bool is_lvalue) { |
| 8899 | | // assert(node->type == NodeTypeArrayAccessExpr); |
| 8900 | | // |
| 8901 | | // LLVMValueRef ptr = gen_array_ptr(g, node); |
| 8902 | | // TypeTableEntry *child_type; |
| 8903 | | // TypeTableEntry *array_type = get_expr_type(node->data.array_access_expr.array_ref_expr); |
| 8904 | | // if (array_type->id == TypeTableEntryIdPointer) { |
| 8905 | | // child_type = array_type->data.pointer.child_type; |
| 8906 | | // } else if (array_type->id == TypeTableEntryIdStruct) { |
| 8907 | | // assert(array_type->data.structure.is_slice); |
| 8908 | | // TypeTableEntry *child_ptr_type = array_type->data.structure.fields[0].type_entry; |
| 8909 | | // assert(child_ptr_type->id == TypeTableEntryIdPointer); |
| 8910 | | // child_type = child_ptr_type->data.pointer.child_type; |
| 8911 | | // } else if (array_type->id == TypeTableEntryIdArray) { |
| 8912 | | // child_type = array_type->data.array.child_type; |
| 8913 | | // } else { |
| 8914 | | // zig_unreachable(); |
| 8915 | | // } |
| 8916 | | // |
| 8917 | | // if (is_lvalue || !ptr || handle_is_ptr(child_type)) { |
| 8918 | | // return ptr; |
| 8919 | | // } else { |
| 8920 | | // return LLVMBuildLoad(g->builder, ptr, ""); |
| 8921 | | // } |
| 8922 | | //} |
| 8923 | | // |
| 8924 | | //static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) { |
| 8925 | | // AstNode *init_expr = node->data.variable_declaration.expr; |
| 8926 | | // if (node->data.variable_declaration.is_const && init_expr) { |
| 8927 | | // TypeTableEntry *init_expr_type = get_expr_type(init_expr); |
| 8928 | | // if (init_expr_type->id == TypeTableEntryIdNumLitFloat || |
| 8929 | | // init_expr_type->id == TypeTableEntryIdNumLitInt) |
| 8930 | | // { |
| 8931 | | // return nullptr; |
| 8932 | | // } |
| 8933 | | // } |
| 8934 | | // |
| 8935 | | // LLVMValueRef init_val = nullptr; |
| 8936 | | // TypeTableEntry *init_val_type; |
| 8937 | | // return gen_var_decl_raw(g, node, &node->data.variable_declaration, false, &init_val, &init_val_type, false); |
| 8938 | | //} |
| 8939 | | // |
| 8940 | | //static LLVMValueRef gen_fence(CodeGen *g, AstNode *node) { |
| 8941 | | // assert(node->type == NodeTypeFnCallExpr); |
| 8942 | | // |
| 8943 | | // AstNode *atomic_order_arg = node->data.fn_call_expr.params.at(0); |
| 8944 | | // ConstExprValue *atomic_order_val = &get_resolved_expr(atomic_order_arg)->const_val; |
| 8945 | | // |
| 8946 | | // assert(atomic_order_val->ok); |
| 8947 | | // |
| 8948 | | // LLVMAtomicOrdering atomic_order = to_LLVMAtomicOrdering((AtomicOrder)atomic_order_val->data.x_enum.tag); |
| 8949 | | // |
| 8950 | | // LLVMBuildFence(g->builder, atomic_order, false, ""); |
| 8951 | | // return nullptr; |
| 8952 | | //} |
| 8953 | | // |
| 8954 | | //static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) { |
| 8955 | | // switch (atomic_order) { |
| 8956 | | // case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered; |
| 8957 | | // case AtomicOrderMonotonic: return LLVMAtomicOrderingMonotonic; |
| 8958 | | // case AtomicOrderAcquire: return LLVMAtomicOrderingAcquire; |
| 8959 | | // case AtomicOrderRelease: return LLVMAtomicOrderingRelease; |
| 8960 | | // case AtomicOrderAcqRel: return LLVMAtomicOrderingAcquireRelease; |
| 8961 | | // case AtomicOrderSeqCst: return LLVMAtomicOrderingSequentiallyConsistent; |
| 8962 | | // } |
| 8963 | | // zig_unreachable(); |
| 8964 | | //} |