| ... | ... | @@ -694,11 +694,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 694 | 694 | .bool_and => return boolBinOp(gz, scope, rl, node, .bool_br_and), |
| 695 | 695 | .bool_or => return boolBinOp(gz, scope, rl, node, .bool_br_or), |
| 696 | 696 | |
| 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), |
| 699 | 699 | |
| 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), |
| 702 | 702 | |
| 703 | 703 | .identifier => return identifier(gz, scope, rl, node), |
| 704 | 704 | |
| ... | ... | @@ -748,7 +748,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 748 | 748 | }, |
| 749 | 749 | .@"return" => return ret(gz, scope, node), |
| 750 | 750 | .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), |
| 752 | 752 | |
| 753 | 753 | .if_simple => return ifExpr(gz, scope, rl.br(), node, tree.ifSimple(node)), |
| 754 | 754 | .@"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 |
| 3029 | 3029 | _ = try gz.addBin(.store, lhs_ptr, result); |
| 3030 | 3030 | } |
| 3031 | 3031 | |
| 3032 | | fn 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 | | |
| 3042 | | fn 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 | | |
| 3052 | | fn 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 | | |
| 3068 | 3032 | fn ptrType( |
| 3069 | 3033 | gz: *GenZir, |
| 3070 | 3034 | scope: *Scope, |
| ... | ... | @@ -6728,14 +6692,16 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Z |
| 6728 | 6692 | return rvalue(gz, rl, result, node); |
| 6729 | 6693 | } |
| 6730 | 6694 | |
| 6731 | | fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 6695 | const Sign = enum { negative, positive }; |
| 6696 | |
| 6697 | fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { |
| 6732 | 6698 | const astgen = gz.astgen; |
| 6733 | 6699 | const tree = astgen.tree; |
| 6734 | 6700 | const main_tokens = tree.nodes.items(.main_token); |
| 6735 | 6701 | |
| 6736 | 6702 | const main_token = main_tokens[node]; |
| 6737 | 6703 | 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: { |
| 6739 | 6705 | assert(bytes[0] == '0'); // validated by tokenizer |
| 6740 | 6706 | break :hex std.fmt.parseHexFloat(f128, bytes) catch |err| switch (err) { |
| 6741 | 6707 | error.InvalidCharacter => unreachable, // validated by tokenizer |
| ... | ... | @@ -6744,6 +6710,10 @@ fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir |
| 6744 | 6710 | } else std.fmt.parseFloat(f128, bytes) catch |err| switch (err) { |
| 6745 | 6711 | error.InvalidCharacter => unreachable, // validated by tokenizer |
| 6746 | 6712 | }; |
| 6713 | const float_number = switch (sign) { |
| 6714 | .negative => -unsigned_float_number, |
| 6715 | .positive => unsigned_float_number, |
| 6716 | }; |
| 6747 | 6717 | // If the value fits into a f64 without losing any precision, store it that way. |
| 6748 | 6718 | @setFloatMode(.Strict); |
| 6749 | 6719 | const smaller_float = @floatCast(f64, float_number); |
| ... | ... | @@ -7651,6 +7621,29 @@ fn simpleUnOp( |
| 7651 | 7621 | return rvalue(gz, rl, result, node); |
| 7652 | 7622 | } |
| 7653 | 7623 | |
| 7624 | fn 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 | |
| 7654 | 7647 | fn cmpxchg( |
| 7655 | 7648 | gz: *GenZir, |
| 7656 | 7649 | scope: *Scope, |