aboutsummaryrefslogtreecommitdiff
path: root/src/value.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-05-10 21:46:24 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-05-10 21:50:55 -0700
commitb33c8b0b06dd6a24d89efb278eeb833db93b2f9b (patch)
tree6b5c91beeae7563c581279f8d08d553e08c40d3f /src/value.zig
parentf5edf78eea403c14635a05e1729672cfb50aca89 (diff)
downloadzig-b33c8b0b06dd6a24d89efb278eeb833db93b2f9b.tar.gz
zig-b33c8b0b06dd6a24d89efb278eeb833db93b2f9b.zip
Sema: comptime float negation supports negative zero
When handling the `negate` ZIR instruction, Zig now checks for a comptime operand and handles it as a special case rather than lowering it as `0 - x` so that the expression `-x` where `x` is a floating point value known at compile-time, will get the negative zero bitwise representation.
Diffstat (limited to 'src/value.zig')
-rw-r--r--src/value.zig32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/value.zig b/src/value.zig
index e8ccada8ed..1e70ad0c54 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -4155,6 +4155,38 @@ pub const Value = extern union {
}
}
+ pub fn floatNeg(
+ val: Value,
+ float_type: Type,
+ arena: Allocator,
+ target: Target,
+ ) !Value {
+ if (float_type.zigTypeTag() == .Vector) {
+ const result_data = try arena.alloc(Value, float_type.vectorLen());
+ for (result_data) |*scalar, i| {
+ scalar.* = try floatNegScalar(val.indexVectorlike(i), float_type.scalarType(), arena, target);
+ }
+ return Value.Tag.aggregate.create(arena, result_data);
+ }
+ return floatNegScalar(val, float_type, arena, target);
+ }
+
+ pub fn floatNegScalar(
+ val: Value,
+ float_type: Type,
+ arena: Allocator,
+ target: Target,
+ ) !Value {
+ switch (float_type.floatBits(target)) {
+ 16 => return Value.Tag.float_16.create(arena, -val.toFloat(f16)),
+ 32 => return Value.Tag.float_32.create(arena, -val.toFloat(f32)),
+ 64 => return Value.Tag.float_64.create(arena, -val.toFloat(f64)),
+ 80 => return Value.Tag.float_80.create(arena, -val.toFloat(f80)),
+ 128 => return Value.Tag.float_128.create(arena, -val.toFloat(f128)),
+ else => unreachable,
+ }
+ }
+
pub fn floatDiv(
lhs: Value,
rhs: Value,