aboutsummaryrefslogtreecommitdiff
path: root/src/AstGen.zig
diff options
context:
space:
mode:
authorTravis Staloch <twostepted@gmail.com>2021-09-08 15:19:03 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-09-28 17:03:41 -0700
commitb9a95f2dd94e6175322d3388c3936eb600ec90ea (patch)
tree186a31fd920ca47bc15c3a426b9dfa8d67756ada /src/AstGen.zig
parent29f41896ed9d99e82a88f4b63efa182ca0d2f93c (diff)
downloadzig-b9a95f2dd94e6175322d3388c3936eb600ec90ea.tar.gz
zig-b9a95f2dd94e6175322d3388c3936eb600ec90ea.zip
sat-arithmetic: add c backend support
- modify AstGen binOpExt()/assignBinOpExt() to accept generic extended payload T - rework Sema zirSatArithmetic() to use existing sema.analyzeArithmetic() by adding an `opt_extended` parameter. - add airSatOp() to codegen/c.zig - add saturating functions to src/link/C/zig.h
Diffstat (limited to 'src/AstGen.zig')
-rw-r--r--src/AstGen.zig62
1 files changed, 32 insertions, 30 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index b3af3eb86b..25452cb386 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -535,7 +535,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
return rvalue(gz, rl, .void_value, node);
},
.assign_bit_shift_left_sat => {
- try assignBinOpExt(gz, scope, node, .shl_with_saturation);
+ try assignBinOpExt(gz, scope, node, .shl_with_saturation, Zir.Inst.SaturatingArithmetic);
return rvalue(gz, rl, .void_value, node);
},
.assign_bit_shift_right => {
@@ -568,7 +568,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
return rvalue(gz, rl, .void_value, node);
},
.assign_sub_sat => {
- try assignBinOpExt(gz, scope, node, .sub_with_saturation);
+ try assignBinOpExt(gz, scope, node, .sub_with_saturation, Zir.Inst.SaturatingArithmetic);
return rvalue(gz, rl, .void_value, node);
},
.assign_mod => {
@@ -584,7 +584,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
return rvalue(gz, rl, .void_value, node);
},
.assign_add_sat => {
- try assignBinOpExt(gz, scope, node, .add_with_saturation);
+ try assignBinOpExt(gz, scope, node, .add_with_saturation, Zir.Inst.SaturatingArithmetic);
return rvalue(gz, rl, .void_value, node);
},
.assign_mul => {
@@ -596,24 +596,24 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
return rvalue(gz, rl, .void_value, node);
},
.assign_mul_sat => {
- try assignBinOpExt(gz, scope, node, .mul_with_saturation);
+ try assignBinOpExt(gz, scope, node, .mul_with_saturation, Zir.Inst.SaturatingArithmetic);
return rvalue(gz, rl, .void_value, node);
},
// zig fmt: off
.bit_shift_left => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl),
- .bit_shift_left_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl_with_saturation),
+ .bit_shift_left_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl_with_saturation, Zir.Inst.SaturatingArithmetic),
.bit_shift_right => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shr),
.add => return simpleBinOp(gz, scope, rl, node, .add),
.add_wrap => return simpleBinOp(gz, scope, rl, node, .addwrap),
- .add_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .add_with_saturation),
+ .add_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .add_with_saturation, Zir.Inst.SaturatingArithmetic),
.sub => return simpleBinOp(gz, scope, rl, node, .sub),
.sub_wrap => return simpleBinOp(gz, scope, rl, node, .subwrap),
- .sub_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .sub_with_saturation),
+ .sub_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .sub_with_saturation, Zir.Inst.SaturatingArithmetic),
.mul => return simpleBinOp(gz, scope, rl, node, .mul),
.mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap),
- .mul_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .mul_with_saturation),
+ .mul_sat => return binOpExt(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .mul_with_saturation, Zir.Inst.SaturatingArithmetic),
.div => return simpleBinOp(gz, scope, rl, node, .div),
.mod => return simpleBinOp(gz, scope, rl, node, .mod_rem),
.bit_and => {
@@ -2713,6 +2713,28 @@ fn assignOp(
_ = try gz.addBin(.store, lhs_ptr, result);
}
+// TODO: is there an existing way to do this?
+// TODO: likely rename this to reflect result_loc == .none or add more params to make it more general
+fn binOpExt(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ infix_node: Ast.Node.Index,
+ lhs_node: Ast.Node.Index,
+ rhs_node: Ast.Node.Index,
+ tag: Zir.Inst.Extended,
+ comptime T: type,
+) InnerError!Zir.Inst.Ref {
+ const lhs = try expr(gz, scope, .none, lhs_node);
+ const rhs = try expr(gz, scope, .none, rhs_node);
+ const result = try gz.addExtendedPayload(tag, T{
+ .node = gz.nodeIndexToRelative(infix_node),
+ .lhs = lhs,
+ .rhs = rhs,
+ });
+ return rvalue(gz, rl, result, infix_node);
+}
+
// TODO: is there an existing method to accomplish this?
// TODO: likely rename this to indicate rhs type coercion or add more params to make it more general
fn assignBinOpExt(
@@ -2720,8 +2742,8 @@ fn assignBinOpExt(
scope: *Scope,
infix_node: Ast.Node.Index,
op_inst_tag: Zir.Inst.Extended,
+ comptime T: type,
) InnerError!void {
- try emitDbgNode(gz, infix_node);
const astgen = gz.astgen;
const tree = astgen.tree;
const node_datas = tree.nodes.items(.data);
@@ -2730,7 +2752,7 @@ fn assignBinOpExt(
const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node);
const lhs_type = try gz.addUnNode(.typeof, lhs, infix_node);
const rhs = try expr(gz, scope, .{ .coerced_ty = lhs_type }, node_datas[infix_node].rhs);
- const result = try gz.addExtendedPayload(op_inst_tag, Zir.Inst.BinNode{
+ const result = try gz.addExtendedPayload(op_inst_tag, T{
.node = gz.nodeIndexToRelative(infix_node),
.lhs = lhs,
.rhs = rhs,
@@ -7903,26 +7925,6 @@ fn shiftOp(
return rvalue(gz, rl, result, node);
}
-// TODO: is there an existing way to do this?
-// TODO: likely rename this to reflect result_loc == .none or add more params to make it more general
-fn binOpExt(
- gz: *GenZir,
- scope: *Scope,
- rl: ResultLoc,
- node: Ast.Node.Index,
- lhs_node: Ast.Node.Index,
- rhs_node: Ast.Node.Index,
- tag: Zir.Inst.Extended,
-) InnerError!Zir.Inst.Ref {
- const lhs = try expr(gz, scope, .none, lhs_node);
- const rhs = try expr(gz, scope, .none, rhs_node);
- const result = try gz.addExtendedPayload(tag, Zir.Inst.Bin{
- .lhs = lhs,
- .rhs = rhs,
- });
- return rvalue(gz, rl, result, node);
-}
-
fn cImport(
gz: *GenZir,
scope: *Scope,