| ... | @@ -535,7 +535,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -535,7 +535,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 535 | return rvalue(gz, rl, .void_value, node); | 535 | return rvalue(gz, rl, .void_value, node); |
| 536 | }, | 536 | }, |
| 537 | .assign_bit_shift_left_sat => { | 537 | .assign_bit_shift_left_sat => { |
| 538 | try assignBinOpExt(gz, scope, node, .shl_with_saturation, Zir.Inst.SaturatingArithmetic); | 538 | try assignOpExt(gz, scope, node, .shl_with_saturation, Zir.Inst.SaturatingArithmetic); |
| 539 | return rvalue(gz, rl, .void_value, node); | 539 | return rvalue(gz, rl, .void_value, node); |
| 540 | }, | 540 | }, |
| 541 | .assign_bit_shift_right => { | 541 | .assign_bit_shift_right => { |
| ... | @@ -568,7 +568,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -568,7 +568,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 568 | return rvalue(gz, rl, .void_value, node); | 568 | return rvalue(gz, rl, .void_value, node); |
| 569 | }, | 569 | }, |
| 570 | .assign_sub_sat => { | 570 | .assign_sub_sat => { |
| 571 | try assignBinOpExt(gz, scope, node, .sub_with_saturation, Zir.Inst.SaturatingArithmetic); | 571 | try assignOpExt(gz, scope, node, .sub_with_saturation, Zir.Inst.SaturatingArithmetic); |
| 572 | return rvalue(gz, rl, .void_value, node); | 572 | return rvalue(gz, rl, .void_value, node); |
| 573 | }, | 573 | }, |
| 574 | .assign_mod => { | 574 | .assign_mod => { |
| ... | @@ -584,7 +584,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -584,7 +584,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 584 | return rvalue(gz, rl, .void_value, node); | 584 | return rvalue(gz, rl, .void_value, node); |
| 585 | }, | 585 | }, |
| 586 | .assign_add_sat => { | 586 | .assign_add_sat => { |
| 587 | try assignBinOpExt(gz, scope, node, .add_with_saturation, Zir.Inst.SaturatingArithmetic); | 587 | try assignOpExt(gz, scope, node, .add_with_saturation, Zir.Inst.SaturatingArithmetic); |
| 588 | return rvalue(gz, rl, .void_value, node); | 588 | return rvalue(gz, rl, .void_value, node); |
| 589 | }, | 589 | }, |
| 590 | .assign_mul => { | 590 | .assign_mul => { |
| ... | @@ -596,26 +596,28 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -596,26 +596,28 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 596 | return rvalue(gz, rl, .void_value, node); | 596 | return rvalue(gz, rl, .void_value, node); |
| 597 | }, | 597 | }, |
| 598 | .assign_mul_sat => { | 598 | .assign_mul_sat => { |
| 599 | try assignBinOpExt(gz, scope, node, .mul_with_saturation, Zir.Inst.SaturatingArithmetic); | 599 | try assignOpExt(gz, scope, node, .mul_with_saturation, Zir.Inst.SaturatingArithmetic); |
| 600 | return rvalue(gz, rl, .void_value, node); | 600 | return rvalue(gz, rl, .void_value, node); |
| 601 | }, | 601 | }, |
| 602 | | 602 | |
| 603 | // zig fmt: off | 603 | // zig fmt: off |
| 604 | .bit_shift_left => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl), | 604 | .bit_shift_left => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl), |
| 605 | .bit_shift_left_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl_with_saturation, Zir.Inst.SaturatingArithmetic), | | |
| 606 | .bit_shift_right => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shr), | 605 | .bit_shift_right => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shr), |
| 607 | | 606 | |
| 608 | .add => return simpleBinOp(gz, scope, rl, node, .add), | 607 | .add => return simpleBinOp(gz, scope, rl, node, .add), |
| 609 | .add_wrap => return simpleBinOp(gz, scope, rl, node, .addwrap), | 608 | .add_wrap => return simpleBinOp(gz, scope, rl, node, .addwrap), |
| 610 | .add_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .add_with_saturation, Zir.Inst.SaturatingArithmetic), | | |
| 611 | .sub => return simpleBinOp(gz, scope, rl, node, .sub), | 609 | .sub => return simpleBinOp(gz, scope, rl, node, .sub), |
| 612 | .sub_wrap => return simpleBinOp(gz, scope, rl, node, .subwrap), | 610 | .sub_wrap => return simpleBinOp(gz, scope, rl, node, .subwrap), |
| 613 | .sub_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .sub_with_saturation, Zir.Inst.SaturatingArithmetic), | | |
| 614 | .mul => return simpleBinOp(gz, scope, rl, node, .mul), | 611 | .mul => return simpleBinOp(gz, scope, rl, node, .mul), |
| 615 | .mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap), | 612 | .mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap), |
| 616 | .mul_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .mul_with_saturation, Zir.Inst.SaturatingArithmetic), | | |
| 617 | .div => return simpleBinOp(gz, scope, rl, node, .div), | 613 | .div => return simpleBinOp(gz, scope, rl, node, .div), |
| 618 | .mod => return simpleBinOp(gz, scope, rl, node, .mod_rem), | 614 | .mod => return simpleBinOp(gz, scope, rl, node, .mod_rem), |
| | 615 | |
| | 616 | .add_sat => return simpleBinOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .add_with_saturation, Zir.Inst.SaturatingArithmetic), |
| | 617 | .sub_sat => return simpleBinOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .sub_with_saturation, Zir.Inst.SaturatingArithmetic), |
| | 618 | .mul_sat => return simpleBinOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .mul_with_saturation, Zir.Inst.SaturatingArithmetic), |
| | 619 | .bit_shift_left_sat => return simpleBinOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl_with_saturation, Zir.Inst.SaturatingArithmetic), |
| | 620 | |
| 619 | .bit_and => { | 621 | .bit_and => { |
| 620 | const current_ampersand_token = main_tokens[node]; | 622 | const current_ampersand_token = main_tokens[node]; |
| 621 | if (token_tags[current_ampersand_token + 1] == .ampersand) { | 623 | if (token_tags[current_ampersand_token + 1] == .ampersand) { |
| ... | @@ -2713,9 +2715,7 @@ fn assignOp( | ... | @@ -2713,9 +2715,7 @@ fn assignOp( |
| 2713 | _ = try gz.addBin(.store, lhs_ptr, result); | 2715 | _ = try gz.addBin(.store, lhs_ptr, result); |
| 2714 | } | 2716 | } |
| 2715 | | 2717 | |
| 2716 | // TODO: is there an existing way to do this? | 2718 | fn simpleBinOpExt( |
| 2717 | // TODO: likely rename this to reflect result_loc == .none or add more params to make it more general | | |
| 2718 | fn binOpExt( | | |
| 2719 | gz: *GenZir, | 2719 | gz: *GenZir, |
| 2720 | scope: *Scope, | 2720 | scope: *Scope, |
| 2721 | rl: ResultLoc, | 2721 | rl: ResultLoc, |
| ... | @@ -2735,9 +2735,7 @@ fn binOpExt( | ... | @@ -2735,9 +2735,7 @@ fn binOpExt( |
| 2735 | return rvalue(gz, rl, result, infix_node); | 2735 | return rvalue(gz, rl, result, infix_node); |
| 2736 | } | 2736 | } |
| 2737 | | 2737 | |
| 2738 | // TODO: is there an existing method to accomplish this? | 2738 | fn assignOpExt( |
| 2739 | // TODO: likely rename this to indicate rhs type coercion or add more params to make it more general | | |
| 2740 | fn assignBinOpExt( | | |
| 2741 | gz: *GenZir, | 2739 | gz: *GenZir, |
| 2742 | scope: *Scope, | 2740 | scope: *Scope, |
| 2743 | infix_node: Ast.Node.Index, | 2741 | infix_node: Ast.Node.Index, |