Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,6 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/multf3.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/multi3.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulxf3.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negXf2.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negXi2.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negv.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/os_version_check.zig"
Expand All @@ -623,11 +622,15 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/sincos.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/sqrt.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/stack_probe.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subdf3.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subo.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subsf3.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subdf3.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subtf3.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subxf3.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negsf2.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negdf2.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negtf2.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negxf2.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/tan.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/trig.zig"
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/trunc.zig"
Expand Down
12 changes: 8 additions & 4 deletions lib/compiler_rt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ comptime {
_ = @import("compiler_rt/atomics.zig");

_ = @import("compiler_rt/addf3.zig");
_ = @import("compiler_rt/adddf3.zig");
_ = @import("compiler_rt/addsf3.zig");
_ = @import("compiler_rt/adddf3.zig");
_ = @import("compiler_rt/addtf3.zig");
_ = @import("compiler_rt/addxf3.zig");
_ = @import("compiler_rt/subdf3.zig");

_ = @import("compiler_rt/subsf3.zig");
_ = @import("compiler_rt/subdf3.zig");
_ = @import("compiler_rt/subtf3.zig");
_ = @import("compiler_rt/subxf3.zig");

Expand All @@ -19,6 +20,11 @@ comptime {
_ = @import("compiler_rt/multf3.zig");
_ = @import("compiler_rt/mulxf3.zig");

_ = @import("compiler_rt/negsf2.zig");
_ = @import("compiler_rt/negdf2.zig");
_ = @import("compiler_rt/negtf2.zig");
_ = @import("compiler_rt/negxf2.zig");

_ = @import("compiler_rt/comparef.zig");
_ = @import("compiler_rt/cmpsf2.zig");
_ = @import("compiler_rt/cmpdf2.zig");
Expand Down Expand Up @@ -172,8 +178,6 @@ comptime {
_ = @import("compiler_rt/mulo.zig");
_ = @import("compiler_rt/cmp.zig");

_ = @import("compiler_rt/negXf2.zig");

_ = @import("compiler_rt/os_version_check.zig");
_ = @import("compiler_rt/emutls.zig");
_ = @import("compiler_rt/arm.zig");
Expand Down
12 changes: 12 additions & 0 deletions lib/compiler_rt/common.zig
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,15 @@ pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeIn
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
return @as(i32, 1) - shift;
}

pub inline fn fneg(a: anytype) @TypeOf(a) {
const F = @TypeOf(a);
const bits = @typeInfo(F).Float.bits;
const U = @Type(.{ .Int = .{
.signedness = .unsigned,
.bits = bits,
} });
const sign_bit_mask = @as(U, 1) << (bits - 1);
const negated = @bitCast(U, a) ^ sign_bit_mask;
return @bitCast(F, negated);
}
42 changes: 0 additions & 42 deletions lib/compiler_rt/negXf2.zig

This file was deleted.

19 changes: 19 additions & 0 deletions lib/compiler_rt/negdf2.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const common = @import("./common.zig");

pub const panic = common.panic;

comptime {
if (common.want_aeabi) {
@export(__aeabi_dneg, .{ .name = "__aeabi_dneg", .linkage = common.linkage });
} else {
@export(__negdf2, .{ .name = "__negdf2", .linkage = common.linkage });
}
}

fn __negdf2(a: f64) callconv(.C) f64 {
return common.fneg(a);
}

fn __aeabi_dneg(a: f64) callconv(.AAPCS) f64 {
return common.fneg(a);
}
19 changes: 19 additions & 0 deletions lib/compiler_rt/negsf2.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const common = @import("./common.zig");

pub const panic = common.panic;

comptime {
if (common.want_aeabi) {
@export(__aeabi_fneg, .{ .name = "__aeabi_fneg", .linkage = common.linkage });
} else {
@export(__negsf2, .{ .name = "__negsf2", .linkage = common.linkage });
}
}

fn __negsf2(a: f32) callconv(.C) f32 {
return common.fneg(a);
}

fn __aeabi_fneg(a: f32) callconv(.AAPCS) f32 {
return common.fneg(a);
}
11 changes: 11 additions & 0 deletions lib/compiler_rt/negtf2.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const common = @import("./common.zig");

pub const panic = common.panic;

comptime {
@export(__negtf2, .{ .name = "__negtf2", .linkage = common.linkage });
}

fn __negtf2(a: f128) callconv(.C) f128 {
return common.fneg(a);
}
11 changes: 11 additions & 0 deletions lib/compiler_rt/negxf2.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const common = @import("./common.zig");

pub const panic = common.panic;

comptime {
@export(__negxf2, .{ .name = "__negxf2", .linkage = common.linkage });
}

fn __negxf2(a: f80) callconv(.C) f80 {
return common.fneg(a);
}
2 changes: 0 additions & 2 deletions lib/std/fmt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2225,7 +2225,6 @@ test "float.scientific.precision" {
}

test "float.special" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
try expectFmt("f64: nan", "f64: {}", .{math.nan_f64});
// negative nan is not defined by IEE 754,
// and ARM thus normalizes it to positive nan
Expand All @@ -2237,7 +2236,6 @@ test "float.special" {
}

test "float.hexadecimal.special" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
try expectFmt("f64: nan", "f64: {x}", .{math.nan_f64});
// negative nan is not defined by IEE 754,
// and ARM thus normalizes it to positive nan
Expand Down
1 change: 0 additions & 1 deletion lib/std/math/copysign.zig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ pub fn copysign(magnitude: anytype, sign: @TypeOf(magnitude)) @TypeOf(magnitude)
}

test "math.copysign" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
try expect(copysign(@as(T, 1.0), @as(T, 1.0)) == 1.0);
try expect(copysign(@as(T, 2.0), @as(T, -2.0)) == -2.0);
Expand Down
1 change: 0 additions & 1 deletion lib/std/math/signbit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub fn signbit(x: anytype) bool {
}

test "math.signbit" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
try expect(!signbit(@as(T, 0.0)));
try expect(!signbit(@as(T, 1.0)));
Expand Down
6 changes: 6 additions & 0 deletions src/Air.zig
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ pub const Inst = struct {
/// Rounds a floating pointer number to the nearest integer towards zero.
/// Uses the `un_op` field.
trunc_float,
/// Float negation. This affects the sign of zero, inf, and NaN, which is impossible
/// to do with sub. Integers are not allowed and must be represented with sub with
/// LHS of zero.
/// Uses the `un_op` field.
neg,

/// `<`. Result type is always bool.
/// Uses the `bin_op` field.
Expand Down Expand Up @@ -970,6 +975,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
.ceil,
.round,
.trunc_float,
.neg,
=> return air.typeOf(datas[inst].un_op),

.cmp_lt,
Expand Down
2 changes: 2 additions & 0 deletions src/Liveness.zig
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ pub fn categorizeOperand(
.ceil,
.round,
.trunc_float,
.neg,
.cmp_lt_errors_len,
=> {
const o = air_datas[inst].un_op;
Expand Down Expand Up @@ -834,6 +835,7 @@ fn analyzeInst(
.ceil,
.round,
.trunc_float,
.neg,
.cmp_lt_errors_len,
.set_err_return_trace,
=> {
Expand Down
4 changes: 3 additions & 1 deletion src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10070,12 +10070,14 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
}

if (rhs_scalar_ty.isAnyFloat()) {
// We handle comptime negation here to ensure negative zero is represented in the bits.
// We handle float negation here to ensure negative zero is represented in the bits.
if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {
if (rhs_val.isUndef()) return sema.addConstUndef(rhs_ty);
const target = sema.mod.getTarget();
return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, target));
}
try sema.requireRuntimeBlock(block, rhs_src);
return block.addUnOp(.neg, rhs);
}

const lhs = if (rhs_ty.zigTypeTag() == .Vector)
Expand Down
3 changes: 2 additions & 1 deletion src/arch/aarch64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.floor,
.ceil,
.round,
.trunc_float
.trunc_float,
.neg,
=> try self.airUnaryMath(inst),

.add_with_overflow => try self.airOverflow(inst),
Expand Down
1 change: 1 addition & 0 deletions src/arch/arm/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ceil,
.round,
.trunc_float,
.neg,
=> try self.airUnaryMath(inst),

.add_with_overflow => try self.airOverflow(inst),
Expand Down
1 change: 1 addition & 0 deletions src/arch/riscv64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ceil,
.round,
.trunc_float,
.neg,
=> try self.airUnaryMath(inst),

.add_with_overflow => try self.airAddWithOverflow(inst),
Expand Down
1 change: 1 addition & 0 deletions src/arch/sparc64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ceil,
.round,
.trunc_float,
.neg,
=> @panic("TODO try self.airUnaryMath(inst)"),

.add_with_overflow => try self.airAddSubWithOverflow(inst),
Expand Down
1 change: 1 addition & 0 deletions src/arch/wasm/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
.log10,
.fabs,
.round,
.neg,

.cmpxchg_weak,
.cmpxchg_strong,
Expand Down
1 change: 1 addition & 0 deletions src/arch/x86_64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ceil,
.round,
.trunc_float,
.neg,
=> try self.airUnaryMath(inst),

.add_with_overflow => try self.airAddSubShlWithOverflow(inst),
Expand Down
16 changes: 16 additions & 0 deletions src/codegen/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1755,6 +1755,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
.mul_sat => try airSatOp(f, inst, "muls_"),
.shl_sat => try airSatOp(f, inst, "shls_"),

.neg => try airNeg(f, inst),

.sqrt,
.sin,
.cos,
Expand Down Expand Up @@ -4098,6 +4100,20 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
return local;
}

fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue {
if (f.liveness.isUnused(inst)) return CValue.none;

const un_op = f.air.instructions.items(.data)[inst].un_op;
const writer = f.object.writer();
const inst_ty = f.air.typeOfIndex(inst);
const operand = try f.resolveInst(un_op);
const local = try f.allocLocal(inst_ty, .Const);
try writer.writeAll("-");
try f.writeCValue(writer, operand);
try writer.writeAll(";\n");
return local;
}

fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
if (f.liveness.isUnused(inst)) return CValue.none;
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
Expand Down
Loading