diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-07-01 15:52:54 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-07-01 15:52:54 -0700 |
| commit | c89dd15e1be4959800dc7092d7dd4375253db7bc (patch) | |
| tree | ca184ae53592efa21e67128a5f891d642d7f1118 /src/stage1/ir.cpp | |
| parent | 5466e87fce581f2ef90ac23bb80b1dbc05836fc6 (diff) | |
| parent | 2360f8c490f3ec684ed64ff28e8c1fade249070b (diff) | |
| download | zig-c89dd15e1be4959800dc7092d7dd4375253db7bc.tar.gz zig-c89dd15e1be4959800dc7092d7dd4375253db7bc.zip | |
Merge remote-tracking branch 'origin/master' into llvm14
Diffstat (limited to 'src/stage1/ir.cpp')
| -rw-r--r-- | src/stage1/ir.cpp | 266 |
1 files changed, 224 insertions, 42 deletions
diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 5694db22ee..52044e9dce 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -3338,6 +3338,32 @@ static void float_div_floor(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { } } +// c = a - b * trunc(a / b) +static float16_t zig_f16_rem(float16_t a, float16_t b) { + float16_t c; + c = f16_div(a, b); + c = f16_roundToInt(c, softfloat_round_minMag, false); + c = f16_mul(b, c); + c = f16_sub(a, c); + return c; +} + +// c = a - b * trunc(a / b) +static void zig_f128M_rem(const float128_t* a, const float128_t* b, float128_t* c) { + f128M_div(a, b, c); + f128M_roundToInt(c, softfloat_round_minMag, false, c); + f128M_mul(b, c, c); + f128M_sub(a, c, c); +} + +// c = a - b * trunc(a / b) +static void zig_extF80M_rem(const extFloat80_t* a, const extFloat80_t* b, extFloat80_t* c) { + extF80M_div(a, b, c); + extF80M_roundToInt(c, softfloat_round_minMag, false, c); + extF80M_mul(b, c, c); + extF80M_sub(a, c, c); +} + static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { assert(op1->type == op2->type); out_val->type = op1->type; @@ -3346,7 +3372,7 @@ static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { } else if (op1->type->id == ZigTypeIdFloat) { switch (op1->type->data.floating.bit_count) { case 16: - out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); + out_val->data.x_f16 = zig_f16_rem(op1->data.x_f16, op2->data.x_f16); return; case 32: out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); @@ -3355,10 +3381,10 @@ static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); return; case 80: - extF80M_rem(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80); + zig_extF80M_rem(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80); return; case 128: - f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); + zig_f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); return; default: zig_unreachable(); @@ -4454,6 +4480,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted return result; } + if (wanted_type->id == ZigTypeIdFloat && actual_type->id == ZigTypeIdFloat) { + if (wanted_type->data.floating.bit_count == actual_type->data.floating.bit_count) { + return result; + } + } + if (wanted_type->id == ZigTypeIdVector && actual_type->id == ZigTypeIdVector) { if (actual_type->data.vector.len != wanted_type->data.vector.len) { result.id = ConstCastResultIdVectorLength; @@ -7817,7 +7849,7 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || !actual_type->data.pointer.is_const); - if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, + if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, array_type->data.array.child_type, source_node, !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk && (slice_ptr_type->data.pointer.sentinel == nullptr || @@ -7825,6 +7857,14 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou const_values_equal(ira->codegen, array_type->data.array.sentinel, slice_ptr_type->data.pointer.sentinel)))) { + if (!const_ok) { + ErrorMsg *msg = ir_add_error_node(ira, source_node, + buf_sprintf("cannot cast pointer to array literal to slice type '%s'", + buf_ptr(&wanted_type->name))); + add_error_note(ira->codegen, msg, source_node, + buf_sprintf("cast discards const qualifier")); + return ira->codegen->invalid_inst_gen; + } // If the pointers both have ABI align, it works. // Or if the array length is 0, alignment doesn't matter. bool ok_align = array_type->data.array.len == 0 || @@ -8182,8 +8222,16 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou ZigType *wanted_child = wanted_type->data.pointer.child_type; bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const); if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) && - wanted_child->data.array.len == field_count && (const_ok || field_count == 0)) + wanted_child->data.array.len == field_count) { + if (!const_ok && field_count != 0) { + ErrorMsg *msg = ir_add_error_node(ira, source_node, + buf_sprintf("cannot cast pointer to array literal to '%s'", + buf_ptr(&wanted_type->name))); + add_error_note(ira->codegen, msg, source_node, + buf_sprintf("cast discards const qualifier")); + return ira->codegen->invalid_inst_gen; + } Stage1AirInst *res = ir_analyze_struct_literal_to_array(ira, scope, source_node, value, anon_type, wanted_child); if (res->value->type->id == ZigTypeIdPointer) return res; @@ -8215,6 +8263,13 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou res = ir_get_ref(ira, scope, source_node, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile); return ir_resolve_ptr_of_array_to_slice(ira, scope, source_node, res, wanted_type, nullptr); + } else if (!slice_type->data.pointer.is_const && actual_type->data.pointer.is_const && field_count != 0) { + ErrorMsg *msg = ir_add_error_node(ira, source_node, + buf_sprintf("cannot cast pointer to array literal to slice type '%s'", + buf_ptr(&wanted_type->name))); + add_error_note(ira->codegen, msg, source_node, + buf_sprintf("cast discards const qualifier")); + return ira->codegen->invalid_inst_gen; } } } @@ -8242,6 +8297,34 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou return ir_implicit_cast2(ira, scope, source_node, cast1, wanted_type); } + // E!T to T + if (actual_type->id == ZigTypeIdErrorUnion) { + if (types_match_const_cast_only(ira, actual_type->data.error_union.payload_type, wanted_type, + source_node, false).id == ConstCastResultIdOk) + { + ErrorMsg *parent_msg = ir_add_error_node(ira, source_node, + buf_sprintf("cannot convert error union to payload type. consider using `try`, `catch`, or `if`. expected type '%s', found '%s'", + buf_ptr(&wanted_type->name), + buf_ptr(&actual_type->name))); + report_recursive_error(ira, source_node, &const_cast_result, parent_msg); + return ira->codegen->invalid_inst_gen; + } + } + + //?T to T + if (actual_type->id == ZigTypeIdOptional) { + if (types_match_const_cast_only(ira, actual_type->data.maybe.child_type, wanted_type, + source_node, false).id == ConstCastResultIdOk) + { + ErrorMsg *parent_msg = ir_add_error_node(ira, source_node, + buf_sprintf("cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type '%s', found '%s'", + buf_ptr(&wanted_type->name), + buf_ptr(&actual_type->name))); + report_recursive_error(ira, source_node, &const_cast_result, parent_msg); + return ira->codegen->invalid_inst_gen; + } + } + ErrorMsg *parent_msg = ir_add_error_node(ira, source_node, buf_sprintf("expected type '%s', found '%s'", buf_ptr(&wanted_type->name), @@ -11666,6 +11749,8 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns case CallingConventionAAPCS: case CallingConventionAAPCSVFP: case CallingConventionSysV: + case CallingConventionWin64: + case CallingConventionPtxKernel: add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc); fn_entry->section_name = section_name; break; @@ -15013,7 +15098,7 @@ static Stage1AirInst *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, Stage1ZirI return ira->codegen->invalid_inst_gen; if (actual_array_type->id != ZigTypeIdArray) { ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, - buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", + buf_sprintf("array literal requires address-of operator (&) to coerce to slice type '%s'", buf_ptr(&actual_array_type->name))); return ira->codegen->invalid_inst_gen; } @@ -15406,12 +15491,22 @@ static Stage1AirInst *ir_analyze_struct_field_ptr(IrAnalyze *ira, Scope *scope, assert(struct_ptr->value->type->id == ZigTypeIdPointer); uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host; uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes; + if (ptr_host_int_bytes > 0) { + ptr_bit_offset += field->offset * 8; + } uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, is_const, is_volatile, PtrLenSingle, field->align, (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), (uint32_t)host_int_bytes_for_result_type, false); + + if (field == struct_type->data.structure.misaligned_field) { + // If field is the last single misaligned field it will be represented as array + // of bytes in LLVM but get_pointer_to_type_extra will set its host_int_bytes to 0. + // We need it not to be 0 so later stage would generate proper bit casting code. + ptr_type->data.pointer.host_int_bytes = host_int_bytes_for_result_type; + } } if (instr_is_comptime(struct_ptr)) { ZigValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); @@ -17418,7 +17513,7 @@ static Stage1AirInst *ir_analyze_instruction_container_init_list(IrAnalyze *ira, if (is_slice(container_type)) { ir_add_error_node(ira, instruction->init_array_type_source_node, - buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", + buf_sprintf("array literal requires address-of operator (&) to coerce to slice type '%s'", buf_ptr(&container_type->name))); return ira->codegen->invalid_inst_gen; } @@ -17893,7 +17988,7 @@ static void ensure_field_index(ZigType *type, const char *field_name, size_t ind static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { Error err; - ZigType *type_info_type = get_builtin_type(ira->codegen, "TypeInfo"); + ZigType *type_info_type = get_builtin_type(ira->codegen, "Type"); assert(type_info_type->id == ZigTypeIdUnion); if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { zig_unreachable(); @@ -18325,7 +18420,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour fields[1]->special = ConstValSpecialStatic; fields[1]->type = g->builtin_types.entry_type; fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type; - // fields: []TypeInfo.EnumField + // fields: []Type.EnumField ensure_field_index(result->type, "fields", 2); ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); @@ -18351,7 +18446,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour enum_field_val->parent.data.p_array.array_val = enum_field_array; enum_field_val->parent.data.p_array.elem_index = enum_field_index; } - // decls: []TypeInfo.Declaration + // decls: []Type.Declaration ensure_field_index(result->type, "decls", 3); if ((err = ir_make_type_info_decls(ira, source_node, fields[3], type_entry->data.enumeration.decls_scope, false))) @@ -18475,7 +18570,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour } else { fields[1]->data.x_optional = nullptr; } - // fields: []TypeInfo.UnionField + // fields: []Type.UnionField ensure_field_index(result->type, "fields", 2); ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); @@ -18517,7 +18612,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour union_field_val->parent.data.p_array.array_val = union_field_array; union_field_val->parent.data.p_array.elem_index = union_field_index; } - // decls: []TypeInfo.Declaration + // decls: []Type.Declaration ensure_field_index(result->type, "decls", 3); if ((err = ir_make_type_info_decls(ira, source_node, fields[3], type_entry->data.unionation.decls_scope, false))) @@ -18551,7 +18646,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour fields[0]->special = ConstValSpecialStatic; fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout); - // fields: []TypeInfo.StructField + // fields: []Type.StructField ensure_field_index(result->type, "fields", 1); ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); @@ -18612,7 +18707,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour struct_field_val->parent.data.p_array.array_val = struct_field_array; struct_field_val->parent.data.p_array.elem_index = struct_field_index; } - // decls: []TypeInfo.Declaration + // decls: []Type.Declaration ensure_field_index(result->type, "decls", 2); if ((err = ir_make_type_info_decls(ira, source_node, fields[2], type_entry->data.structure.decls_scope, false))) @@ -18637,7 +18732,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour ZigValue **fields = alloc_const_vals_ptrs(g, 7); result->data.x_struct.fields = fields; - // calling_convention: TypeInfo.CallingConvention + // calling_convention: Type.CallingConvention ensure_field_index(result->type, "calling_convention", 0); fields[0]->special = ConstValSpecialStatic; fields[0]->type = get_builtin_type(g, "CallingConvention"); @@ -18672,8 +18767,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; fields[4]->data.x_optional = return_type; } - // args: []TypeInfo.FnArg - ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); + // args: []Type.Fn.Param + ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "Param", result->type); if ((err = type_resolve(g, type_info_fn_arg_type, ResolveStatusSizeKnown))) { zig_unreachable(); } @@ -18743,7 +18838,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour ZigValue **fields = alloc_const_vals_ptrs(g, 1); result->data.x_struct.fields = fields; - // decls: []TypeInfo.Declaration + // decls: []Type.Declaration ensure_field_index(result->type, "decls", 0); if ((err = ir_make_type_info_decls(ira, source_node, fields[0], type_entry->data.opaque.decls_scope, false))) @@ -19116,7 +19211,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index]; size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint); if (decls_len != 0) { - ir_add_error_node(ira, source_node, buf_create_from_str("TypeInfo.Struct.decls must be empty for @Type")); + ir_add_error_node(ira, source_node, buf_create_from_str("Type.Struct.decls must be empty for @Type")); return ira->codegen->invalid_inst_gen->value->type; } @@ -19233,7 +19328,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index]; size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint); if (decls_len != 0) { - ir_add_error_node(ira, source_node, buf_create_from_str("TypeInfo.Struct.decls must be empty for @Type")); + ir_add_error_node(ira, source_node, buf_create_from_str("Type.Struct.decls must be empty for @Type")); return ira->codegen->invalid_inst_gen->value->type; } @@ -19317,7 +19412,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ return ira->codegen->invalid_inst_gen->value->type; if (tag_type->id != ZigTypeIdInt) { ir_add_error_node(ira, source_node, buf_sprintf( - "TypeInfo.Enum.tag_type must be an integer type, not '%s'", buf_ptr(&tag_type->name))); + "Type.Enum.tag_type must be an integer type, not '%s'", buf_ptr(&tag_type->name))); return ira->codegen->invalid_inst_gen->value->type; } @@ -19340,7 +19435,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index]; size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint); if (decls_len != 0) { - ir_add_error_node(ira, source_node, buf_create_from_str("TypeInfo.Enum.decls must be empty for @Type")); + ir_add_error_node(ira, source_node, buf_create_from_str("Type.Enum.decls must be empty for @Type")); return ira->codegen->invalid_inst_gen->value->type; } @@ -19427,7 +19522,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index]; size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint); if (decls_len != 0) { - ir_add_error_node(ira, source_node, buf_create_from_str("TypeInfo.Union.decls must be empty for @Type")); + ir_add_error_node(ira, source_node, buf_create_from_str("Type.Union.decls must be empty for @Type")); return ira->codegen->invalid_inst_gen->value->type; } @@ -19493,7 +19588,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ if ((err = get_const_field_bool(ira, source_node, payload, "is_generic", 2, &is_generic))) return ira->codegen->invalid_inst_gen->value->type; if (is_generic) { - ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.Fn.is_generic must be false for @Type")); + ir_add_error_node(ira, source_node, buf_sprintf("Type.Fn.is_generic must be false for @Type")); return ira->codegen->invalid_inst_gen->value->type; } @@ -19507,7 +19602,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ ZigType *return_type = get_const_field_meta_type_optional(ira, source_node, payload, "return_type", 4); if (return_type == nullptr) { - ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.Fn.return_type must be non-null for @Type")); + ir_add_error_node(ira, source_node, buf_sprintf("Type.Fn.return_type must be non-null for @Type")); return ira->codegen->invalid_inst_gen->value->type; } @@ -19536,14 +19631,13 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ assert(args_arr->data.x_array.special == ConstArraySpecialNone); for (size_t i = 0; i < args_len; i++) { ZigValue *arg_value = &args_arr->data.x_array.data.s_none.elements[i]; - assert(arg_value->type == ir_type_info_get_type(ira, "FnArg", nullptr)); FnTypeParamInfo *info = &fn_type_id.param_info[i]; Error err; bool is_generic; if ((err = get_const_field_bool(ira, source_node, arg_value, "is_generic", 0, &is_generic))) return ira->codegen->invalid_inst_gen->value->type; if (is_generic) { - ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.FnArg.is_generic must be false for @Type")); + ir_add_error_node(ira, source_node, buf_sprintf("Type.Fn.Param.is_generic must be false for @Type")); return ira->codegen->invalid_inst_gen->value->type; } if ((err = get_const_field_bool(ira, source_node, arg_value, "is_noalias", 1, &info->is_noalias))) @@ -19551,7 +19645,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ ZigType *type = get_const_field_meta_type_optional( ira, source_node, arg_value, "arg_type", 2); if (type == nullptr) { - ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.FnArg.arg_type must be non-null for @Type")); + ir_add_error_node(ira, source_node, buf_sprintf("Type.Fn.Param.arg_type must be non-null for @Type")); return ira->codegen->invalid_inst_gen->value->type; } info->type = type; @@ -22975,6 +23069,12 @@ static Stage1AirInst *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, Stage1ZirI if (type_is_invalid(src_type)) return ira->codegen->invalid_inst_gen; + // This logic is not quite right; this is just to get stage1 to accept valid code + // we use in the self-hosted compiler. + if (is_slice(dest_type) && is_slice(src_type)) { + return ir_analyze_bit_cast(ira, instruction->base.scope, instruction->base.source_node, ptr, dest_type); + } + bool keep_bigger_alignment = true; return ir_analyze_ptr_cast(ira, instruction->base.scope, instruction->base.source_node, ptr, instruction->ptr->source_node, dest_type, dest_type_value->source_node, @@ -24039,6 +24139,9 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_ case BuiltinFnIdCos: out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16))); break; + case BuiltinFnIdTan: + out_val->data.x_f16 = zig_double_to_f16(tan(zig_f16_to_double(op->data.x_f16))); + break; case BuiltinFnIdExp: out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16))); break; @@ -24088,6 +24191,9 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_ case BuiltinFnIdCos: out_val->data.x_f32 = cosf(op->data.x_f32); break; + case BuiltinFnIdTan: + out_val->data.x_f32 = tanf(op->data.x_f32); + break; case BuiltinFnIdExp: out_val->data.x_f32 = expf(op->data.x_f32); break; @@ -24137,6 +24243,9 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_ case BuiltinFnIdCos: out_val->data.x_f64 = cos(op->data.x_f64); break; + case BuiltinFnIdTan: + out_val->data.x_f64 = tan(op->data.x_f64); + break; case BuiltinFnIdExp: out_val->data.x_f64 = exp(op->data.x_f64); break; @@ -24200,6 +24309,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_ case BuiltinFnIdNearbyInt: case BuiltinFnIdSin: case BuiltinFnIdCos: + case BuiltinFnIdTan: case BuiltinFnIdExp: case BuiltinFnIdExp2: case BuiltinFnIdLog: @@ -24207,7 +24317,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_ case BuiltinFnIdLog2: return ir_add_error_node(ira, source_node, buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026", - float_op_to_name(fop), buf_ptr(&float_type->name))); + float_un_op_to_name(fop), buf_ptr(&float_type->name))); default: zig_unreachable(); } @@ -24234,24 +24344,94 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_ break; case BuiltinFnIdCeil: f128M_roundToInt(in, softfloat_round_max, false, out); - break; + break; case BuiltinFnIdTrunc: f128M_trunc(in, out); break; case BuiltinFnIdRound: f128M_roundToInt(in, softfloat_round_near_maxMag, false, out); break; - case BuiltinFnIdNearbyInt: - case BuiltinFnIdSin: - case BuiltinFnIdCos: - case BuiltinFnIdExp: - case BuiltinFnIdExp2: - case BuiltinFnIdLog: - case BuiltinFnIdLog10: - case BuiltinFnIdLog2: - return ir_add_error_node(ira, source_node, - buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026", - float_op_to_name(fop), buf_ptr(&float_type->name))); + case BuiltinFnIdNearbyInt: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = nearbyint(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } + case BuiltinFnIdSin: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = sin(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } + case BuiltinFnIdCos: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = cos(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } + case BuiltinFnIdTan: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = tan(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } + case BuiltinFnIdExp: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = exp(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } + case BuiltinFnIdExp2: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = exp2(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } + case BuiltinFnIdLog: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = log(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } + case BuiltinFnIdLog10: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = log10(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } + case BuiltinFnIdLog2: { + float64_t f64_value = f128M_to_f64(in); + double double_value; + memcpy(&double_value, &f64_value, sizeof(double)); + double_value = log2(double_value); + memcpy(&f64_value, &double_value, sizeof(double)); + f64_to_f128M(f64_value, out); + break; + } default: zig_unreachable(); } @@ -24601,7 +24781,9 @@ static Stage1AirInst *ir_analyze_instruction_end_expr(IrAnalyze *ira, Stage1ZirI if (type_is_invalid(store_ptr->value->type)) { if (instruction->result_loc->id == ResultLocIdReturn && (value->value->type->id == ZigTypeIdErrorUnion || value->value->type->id == ZigTypeIdErrorSet) && - ira->explicit_return_type->id != ZigTypeIdErrorUnion && ira->explicit_return_type->id != ZigTypeIdErrorSet) + ira->explicit_return_type->id != ZigTypeIdErrorUnion && ira->explicit_return_type->id != ZigTypeIdErrorSet && + // Only add error note if we have a node to attach it to + ira->explicit_return_type_source_node) { add_error_note(ira->codegen, ira->new_irb.exec->first_err_trace_msg, ira->explicit_return_type_source_node, buf_create_from_str("function cannot return an error")); |
