diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 74ca8b814c..528d191be9 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -29,10 +29,30 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if left_type.is_number() && !left_type.is_ptr() && right_type in [ast.int_literal_type, ast.float_literal_type] { node.right_type = left_type + if left_type in [ast.f32_type_idx, ast.f64_type_idx] && right_type == ast.float_literal_type { + defer { + node.right = ast.CastExpr{ + expr: node.right + typ: left_type + typname: c.table.get_type_name(left_type) + expr_type: right_type + } + } + } } if right_type.is_number() && !right_type.is_ptr() && left_type in [ast.int_literal_type, ast.float_literal_type] { node.left_type = right_type + if right_type in [ast.f32_type_idx, ast.f64_type_idx] && left_type == ast.float_literal_type { + defer { + node.left = ast.CastExpr{ + expr: node.left + typ: right_type + typname: c.table.get_type_name(right_type) + expr_type: left_type + } + } + } } mut right_sym := c.table.sym(right_type) right_final_sym := c.table.final_sym(right_type) diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v index 569e3a7054..080dc0c1b5 100644 --- a/vlib/v/gen/native/amd64.v +++ b/vlib/v/gen/native/amd64.v @@ -1681,6 +1681,7 @@ pub fn (mut g Gen) call_fn_amd64(node ast.CallExpr) { } } + args_offset := args.len args << node.args args_size := args.map(g.get_type_size(it.typ)) is_floats := args.map(it.typ.is_pure_float()) @@ -1751,6 +1752,10 @@ pub fn (mut g Gen) call_fn_amd64(node ast.CallExpr) { } } if is_floats[i] { + if args_size[i] == 8 && node.expected_arg_types[i + args_offset] == ast.f32_type_idx { + g.write32(0xc05a0ff2) + g.println('cvtsd2ss xmm0, xmm0') + } g.push_sse(.xmm0) } else { match args_size[i] { @@ -2417,6 +2422,7 @@ fn (mut g Gen) gen_left_value(node ast.Expr) { fn (mut g Gen) prefix_expr(node ast.PrefixExpr) { match node.op { .minus { + // TODO neg float g.expr(node.right) g.neg(.rax) } @@ -2471,15 +2477,6 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.pop_sse(.xmm1) } } - // left: xmm0, right: xmm1 - if node.left is ast.FloatLiteral && node.right_type == ast.f32_type_idx { - g.write32(0xc05a0ff2) - g.println('cvtsd2ss xmm0, xmm0') - } - if node.left_type == ast.f32_type_idx && node.right is ast.FloatLiteral { - g.write32(0xc95a0ff2) - g.println('cvtsd2ss xmm1, xmm1') - } match node.op { .eq, .ne { g.write32(0xc1c20ff3) diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index a0c72bc471..935607f993 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -62,6 +62,7 @@ mut: structs []Struct eval eval.Eval enum_vals map[string]Enum + return_type ast.Type // macho specific macho_ncmds int macho_cmdsize int @@ -920,6 +921,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) { g.register_function_address(name) g.labels = &LabelTable{} g.defer_stmts.clear() + g.return_type = node.return_type if g.pref.arch == .arm64 { g.fn_decl_arm64(node) } else { @@ -1157,8 +1159,14 @@ fn (mut g Gen) stmt(node ast.Stmt) { g.expr(e0) } } - // store the struct value typ := node.types[0] + if typ == ast.float_literal_type_idx && g.return_type == ast.f32_type_idx { + if g.pref.arch == .amd64 { + g.write32(0xc05a0ff2) + g.println('cvtsd2ss xmm0, xmm0') + } + } + // store the struct value if !typ.is_real_pointer() && !typ.is_number() && !typ.is_bool() { ts := g.table.sym(typ) size := g.get_type_size(typ) diff --git a/vlib/v/gen/native/tests/float.vv b/vlib/v/gen/native/tests/float.vv index 648b2d576f..04ec7d5cae 100644 --- a/vlib/v/gen/native/tests/float.vv +++ b/vlib/v/gen/native/tests/float.vv @@ -41,13 +41,12 @@ fn float_cast_test() { assert l == 10000000000000000000 } -// TODO return float literal fn get_f32() f32 { - return f32(2.5) + return 2.5 } fn get_f64() f64 { - return f64(3.6) + return 3.6 } fn add_float(a int, b f32, c u64, d f64) f64 { @@ -60,8 +59,7 @@ fn float_fn_test() { b := get_f64() assert b == 3.6 - // TODO pass float literal - c := add_float(3, f32(6.5), 2, f64(4.3)) + c := add_float(3, 6.5, 2, 4.3) assert c - 10.8 < 0.00001 } diff --git a/vlib/v/tests/sizeof_test.v b/vlib/v/tests/sizeof_test.v index 34a808523f..ee59436901 100644 --- a/vlib/v/tests/sizeof_test.v +++ b/vlib/v/tests/sizeof_test.v @@ -11,7 +11,7 @@ struct S2 { fn test_math_sizeof() { r := math.f32_from_bits(sizeof(int)) - assert r > 5.6e-45 && r < 5.7e-45 + assert f64(r) > 5.6e-45 && f64(r) < 5.7e-45 } fn test_sizeof() {