authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-28 17:11:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-28 17:11:42-07:00
logd8e99164d35fbbcd7e33773e9f35be70d184eaf5
tree230234cb6e8ddb2064bd770c83d5044e444ce45d
parent18d6523888ef08bc66eb808075d13c5e00b8fcf4

AstGen: encode negativity into float literals

rather than a separate negation instruction. closes #11545

1 files changed, 36 insertions(+), 43 deletions(-)

src/AstGen.zig+36-43
......@@ -694,11 +694,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
694694 .bool_and => return boolBinOp(gz, scope, rl, node, .bool_br_and),
695695 .bool_or => return boolBinOp(gz, scope, rl, node, .bool_br_or),
696696
697 .bool_not => return boolNot(gz, scope, rl, node),
698 .bit_not => return bitNot(gz, scope, rl, node),
697 .bool_not => return simpleUnOp(gz, scope, rl, node, bool_rl, node_datas[node].lhs, .bool_not),
698 .bit_not => return simpleUnOp(gz, scope, rl, node, .none, node_datas[node].lhs, .bit_not),
699699
700 .negation => return negation(gz, scope, rl, node, .negate),
701 .negation_wrap => return negation(gz, scope, rl, node, .negate_wrap),
700 .negation => return negation(gz, scope, rl, node),
701 .negation_wrap => return simpleUnOp(gz, scope, rl, node, .none, node_datas[node].lhs, .negate_wrap),
702702
703703 .identifier => return identifier(gz, scope, rl, node),
704704
......@@ -748,7 +748,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
748748 },
749749 .@"return" => return ret(gz, scope, node),
750750 .field_access => return fieldAccess(gz, scope, rl, node),
751 .float_literal => return floatLiteral(gz, rl, node),
751 .float_literal => return floatLiteral(gz, rl, node, .positive),
752752
753753 .if_simple => return ifExpr(gz, scope, rl.br(), node, tree.ifSimple(node)),
754754 .@"if" => return ifExpr(gz, scope, rl.br(), node, tree.ifFull(node)),
......@@ -3029,42 +3029,6 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE
30293029 _ = try gz.addBin(.store, lhs_ptr, result);
30303030}
30313031
3032fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
3033 const astgen = gz.astgen;
3034 const tree = astgen.tree;
3035 const node_datas = tree.nodes.items(.data);
3036
3037 const operand = try expr(gz, scope, bool_rl, node_datas[node].lhs);
3038 const result = try gz.addUnNode(.bool_not, operand, node);
3039 return rvalue(gz, rl, result, node);
3040}
3041
3042fn bitNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
3043 const astgen = gz.astgen;
3044 const tree = astgen.tree;
3045 const node_datas = tree.nodes.items(.data);
3046
3047 const operand = try expr(gz, scope, .none, node_datas[node].lhs);
3048 const result = try gz.addUnNode(.bit_not, operand, node);
3049 return rvalue(gz, rl, result, node);
3050}
3051
3052fn negation(
3053 gz: *GenZir,
3054 scope: *Scope,
3055 rl: ResultLoc,
3056 node: Ast.Node.Index,
3057 tag: Zir.Inst.Tag,
3058) InnerError!Zir.Inst.Ref {
3059 const astgen = gz.astgen;
3060 const tree = astgen.tree;
3061 const node_datas = tree.nodes.items(.data);
3062
3063 const operand = try expr(gz, scope, .none, node_datas[node].lhs);
3064 const result = try gz.addUnNode(tag, operand, node);
3065 return rvalue(gz, rl, result, node);
3066}
3067
30683032fn ptrType(
30693033 gz: *GenZir,
30703034 scope: *Scope,
......@@ -6728,14 +6692,16 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Z
67286692 return rvalue(gz, rl, result, node);
67296693}
67306694
6731fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
6695const Sign = enum { negative, positive };
6696
6697fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref {
67326698 const astgen = gz.astgen;
67336699 const tree = astgen.tree;
67346700 const main_tokens = tree.nodes.items(.main_token);
67356701
67366702 const main_token = main_tokens[node];
67376703 const bytes = tree.tokenSlice(main_token);
6738 const float_number: f128 = if (bytes.len > 2 and bytes[1] == 'x') hex: {
6704 const unsigned_float_number: f128 = if (bytes.len > 2 and bytes[1] == 'x') hex: {
67396705 assert(bytes[0] == '0'); // validated by tokenizer
67406706 break :hex std.fmt.parseHexFloat(f128, bytes) catch |err| switch (err) {
67416707 error.InvalidCharacter => unreachable, // validated by tokenizer
......@@ -6744,6 +6710,10 @@ fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir
67446710 } else std.fmt.parseFloat(f128, bytes) catch |err| switch (err) {
67456711 error.InvalidCharacter => unreachable, // validated by tokenizer
67466712 };
6713 const float_number = switch (sign) {
6714 .negative => -unsigned_float_number,
6715 .positive => unsigned_float_number,
6716 };
67476717 // If the value fits into a f64 without losing any precision, store it that way.
67486718 @setFloatMode(.Strict);
67496719 const smaller_float = @floatCast(f64, float_number);
......@@ -7651,6 +7621,29 @@ fn simpleUnOp(
76517621 return rvalue(gz, rl, result, node);
76527622}
76537623
7624fn negation(
7625 gz: *GenZir,
7626 scope: *Scope,
7627 rl: ResultLoc,
7628 node: Ast.Node.Index,
7629) InnerError!Zir.Inst.Ref {
7630 const astgen = gz.astgen;
7631 const tree = astgen.tree;
7632 const node_tags = tree.nodes.items(.tag);
7633 const node_datas = tree.nodes.items(.data);
7634
7635 // Check for float literal as the sub-expression because we want to preserve
7636 // its negativity rather than having it go through comptime subtraction.
7637 const operand_node = node_datas[node].lhs;
7638 if (node_tags[operand_node] == .float_literal) {
7639 return floatLiteral(gz, rl, operand_node, .negative);
7640 }
7641
7642 const operand = try expr(gz, scope, .none, operand_node);
7643 const result = try gz.addUnNode(.negate, operand, node);
7644 return rvalue(gz, rl, result, node);
7645}
7646
76547647fn cmpxchg(
76557648 gz: *GenZir,
76567649 scope: *Scope,