aboutsummaryrefslogtreecommitdiff
path: root/src/value.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-09-28 22:21:15 -0400
committerGitHub <noreply@github.com>2021-09-28 22:21:15 -0400
commitcf90cb7218d1baa56586477bab50e88fdb6be0bb (patch)
treea3495ecdbbca9a963f514938f20003f1aeb69b64 /src/value.zig
parent79bc5891c1c4cde0592fe1b10b6c9a85914155cf (diff)
parent54675824449d16029fdf6a1873e78cb8f2147f60 (diff)
downloadzig-cf90cb7218d1baa56586477bab50e88fdb6be0bb.tar.gz
zig-cf90cb7218d1baa56586477bab50e88fdb6be0bb.zip
Merge pull request #9679 from travisstaloch/sat-arith-operators
sat-arithmetic: add operator support
Diffstat (limited to 'src/value.zig')
-rw-r--r--src/value.zig87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/value.zig b/src/value.zig
index 29d8fa8db9..73a2b3a49f 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -1589,6 +1589,35 @@ pub const Value = extern union {
}
/// Supports both floats and ints; handles undefined.
+ pub fn numberAddSat(
+ lhs: Value,
+ rhs: Value,
+ ty: Type,
+ arena: *Allocator,
+ target: Target,
+ ) !Value {
+ if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
+
+ if (ty.isAnyFloat()) {
+ // TODO: handle outside float range
+ return floatAdd(lhs, rhs, ty, arena);
+ }
+ const result = try intAdd(lhs, rhs, arena);
+
+ const max = try ty.maxInt(arena, target);
+ if (compare(result, .gt, max, ty)) {
+ return max;
+ }
+
+ const min = try ty.minInt(arena, target);
+ if (compare(result, .lt, min, ty)) {
+ return min;
+ }
+
+ return result;
+ }
+
+ /// Supports both floats and ints; handles undefined.
pub fn numberSubWrap(
lhs: Value,
rhs: Value,
@@ -1617,6 +1646,35 @@ pub const Value = extern union {
}
/// Supports both floats and ints; handles undefined.
+ pub fn numberSubSat(
+ lhs: Value,
+ rhs: Value,
+ ty: Type,
+ arena: *Allocator,
+ target: Target,
+ ) !Value {
+ if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
+
+ if (ty.isAnyFloat()) {
+ // TODO: handle outside float range
+ return floatSub(lhs, rhs, ty, arena);
+ }
+ const result = try intSub(lhs, rhs, arena);
+
+ const max = try ty.maxInt(arena, target);
+ if (compare(result, .gt, max, ty)) {
+ return max;
+ }
+
+ const min = try ty.minInt(arena, target);
+ if (compare(result, .lt, min, ty)) {
+ return min;
+ }
+
+ return result;
+ }
+
+ /// Supports both floats and ints; handles undefined.
pub fn numberMulWrap(
lhs: Value,
rhs: Value,
@@ -1645,6 +1703,35 @@ pub const Value = extern union {
}
/// Supports both floats and ints; handles undefined.
+ pub fn numberMulSat(
+ lhs: Value,
+ rhs: Value,
+ ty: Type,
+ arena: *Allocator,
+ target: Target,
+ ) !Value {
+ if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
+
+ if (ty.isAnyFloat()) {
+ // TODO: handle outside float range
+ return floatMul(lhs, rhs, ty, arena);
+ }
+ const result = try intMul(lhs, rhs, arena);
+
+ const max = try ty.maxInt(arena, target);
+ if (compare(result, .gt, max, ty)) {
+ return max;
+ }
+
+ const min = try ty.minInt(arena, target);
+ if (compare(result, .lt, min, ty)) {
+ return min;
+ }
+
+ return result;
+ }
+
+ /// Supports both floats and ints; handles undefined.
pub fn numberMax(lhs: Value, rhs: Value, arena: *Allocator) !Value {
if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);