native, checker: cast float_literal to f32 explicitly in code gen (#16254)

This commit is contained in:
lemon 2022-10-30 17:31:18 +09:00 committed by GitHub
parent 93d765eeee
commit 54b623743d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 16 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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
}

View File

@ -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() {