diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-04-28 13:34:38 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-28 13:34:38 -0400 |
| commit | 360ecc1a2f72967f3a3882b3327e130bdc4e18c0 (patch) | |
| tree | c02dfab372e5b79bc2130d666c5e0a0e5cb3af2e /src/value.zig | |
| parent | d5fcb509881e1b022d2bcef303b53b4f67db1c9a (diff) | |
| parent | 11911f55a73a49e2fda85bddd38d1993b93547c9 (diff) | |
| download | zig-360ecc1a2f72967f3a3882b3327e130bdc4e18c0.tar.gz zig-360ecc1a2f72967f3a3882b3327e130bdc4e18c0.zip | |
Merge pull request #11532 from ziglang/compiler-rt-math
compiler-rt math functions reorg
Diffstat (limited to 'src/value.zig')
| -rw-r--r-- | src/value.zig | 149 |
1 files changed, 50 insertions, 99 deletions
diff --git a/src/value.zig b/src/value.zig index bb7b742290..d2de389de9 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1155,6 +1155,7 @@ pub const Value = extern union { 16 => return floatWriteToMemory(f16, val.toFloat(f16), target, buffer), 32 => return floatWriteToMemory(f32, val.toFloat(f32), target, buffer), 64 => return floatWriteToMemory(f64, val.toFloat(f64), target, buffer), + 80 => return floatWriteToMemory(f80, val.toFloat(f80), target, buffer), 128 => return floatWriteToMemory(f128, val.toFloat(f128), target, buffer), else => unreachable, }, @@ -1379,25 +1380,21 @@ pub const Value = extern union { } fn floatWriteToMemory(comptime F: type, f: F, target: Target, buffer: []u8) void { + const endian = target.cpu.arch.endian(); if (F == f80) { - switch (target.cpu.arch) { - .i386, .x86_64 => { - const repr = std.math.break_f80(f); - std.mem.writeIntLittle(u64, buffer[0..8], repr.fraction); - std.mem.writeIntLittle(u16, buffer[8..10], repr.exp); - // TODO set the rest of the bytes to undefined. should we use 0xaa - // or is there a different way? - return; - }, - else => {}, - } + const repr = std.math.break_f80(f); + std.mem.writeInt(u64, buffer[0..8], repr.fraction, endian); + std.mem.writeInt(u16, buffer[8..10], repr.exp, endian); + // TODO set the rest of the bytes to undefined. should we use 0xaa + // or is there a different way? + return; } const Int = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = @typeInfo(F).Float.bits, } }); const int = @bitCast(Int, f); - std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], int, target.cpu.arch.endian()); + std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], int, endian); } fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F { @@ -2869,9 +2866,7 @@ pub const Value = extern union { 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)), 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)), 64 => return Value.Tag.float_64.create(arena, @intToFloat(f64, x)), - // We can't lower this properly on non-x86 llvm backends yet - //80 => return Value.Tag.float_80.create(arena, @intToFloat(f80, x)), - 80 => @panic("TODO f80 intToFloat"), + 80 => return Value.Tag.float_80.create(arena, @intToFloat(f80, x)), 128 => return Value.Tag.float_128.create(arena, @intToFloat(f128, x)), else => unreachable, } @@ -2908,9 +2903,9 @@ pub const Value = extern union { } const isNegative = std.math.signbit(value); - value = std.math.fabs(value); + value = @fabs(value); - const floored = std.math.floor(value); + const floored = @floor(value); var rational = try std.math.big.Rational.init(arena); defer rational.deinit(); @@ -2941,7 +2936,7 @@ pub const Value = extern union { return 1; } - const w_value = std.math.fabs(scalar); + const w_value = @fabs(scalar); return @divFloor(@floatToInt(std.math.big.Limb, std.math.log2(w_value)), @typeInfo(std.math.big.Limb).Int.bits) + 1; } @@ -3737,9 +3732,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @rem(lhs_val, rhs_val)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt __remx"); - } const lhs_val = lhs.toFloat(f80); const rhs_val = rhs.toFloat(f80); return Value.Tag.float_80.create(arena, @rem(lhs_val, rhs_val)); @@ -3782,9 +3774,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @mod(lhs_val, rhs_val)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt __modx"); - } const lhs_val = lhs.toFloat(f80); const rhs_val = rhs.toFloat(f80); return Value.Tag.float_80.create(arena, @mod(lhs_val, rhs_val)); @@ -4198,9 +4187,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, lhs_val / rhs_val); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt __divxf3"); - } const lhs_val = lhs.toFloat(f80); const rhs_val = rhs.toFloat(f80); return Value.Tag.float_80.create(arena, lhs_val / rhs_val); @@ -4255,9 +4241,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @divFloor(lhs_val, rhs_val)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt __floorx"); - } const lhs_val = lhs.toFloat(f80); const rhs_val = rhs.toFloat(f80); return Value.Tag.float_80.create(arena, @divFloor(lhs_val, rhs_val)); @@ -4312,9 +4295,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @divTrunc(lhs_val, rhs_val)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt __truncx"); - } const lhs_val = lhs.toFloat(f80); const rhs_val = rhs.toFloat(f80); return Value.Tag.float_80.create(arena, @divTrunc(lhs_val, rhs_val)); @@ -4369,9 +4349,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, lhs_val * rhs_val); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt __mulxf3"); - } const lhs_val = lhs.toFloat(f80); const rhs_val = rhs.toFloat(f80); return Value.Tag.float_80.create(arena, lhs_val * rhs_val); @@ -4411,16 +4388,10 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @sqrt(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt __sqrtx"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @sqrt(f)); }, 128 => { - if (true) { - @panic("TODO implement compiler_rt sqrtq"); - } const f = val.toFloat(f128); return Value.Tag.float_128.create(arena, @sqrt(f)); }, @@ -4454,16 +4425,10 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @sin(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt sin for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @sin(f)); }, 128 => { - if (true) { - @panic("TODO implement compiler_rt sin for f128"); - } const f = val.toFloat(f128); return Value.Tag.float_128.create(arena, @sin(f)); }, @@ -4497,16 +4462,10 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @cos(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt cos for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @cos(f)); }, 128 => { - if (true) { - @panic("TODO implement compiler_rt cos for f128"); - } const f = val.toFloat(f128); return Value.Tag.float_128.create(arena, @cos(f)); }, @@ -4514,6 +4473,43 @@ pub const Value = extern union { } } + pub fn tan(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value { + if (float_type.zigTypeTag() == .Vector) { + const result_data = try arena.alloc(Value, float_type.vectorLen()); + for (result_data) |*scalar, i| { + scalar.* = try tanScalar(val.indexVectorlike(i), float_type.scalarType(), arena, target); + } + return Value.Tag.aggregate.create(arena, result_data); + } + return tanScalar(val, float_type, arena, target); + } + + pub fn tanScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value { + switch (float_type.floatBits(target)) { + 16 => { + const f = val.toFloat(f16); + return Value.Tag.float_16.create(arena, @tan(f)); + }, + 32 => { + const f = val.toFloat(f32); + return Value.Tag.float_32.create(arena, @tan(f)); + }, + 64 => { + const f = val.toFloat(f64); + return Value.Tag.float_64.create(arena, @tan(f)); + }, + 80 => { + const f = val.toFloat(f80); + return Value.Tag.float_80.create(arena, @tan(f)); + }, + 128 => { + const f = val.toFloat(f128); + return Value.Tag.float_128.create(arena, @tan(f)); + }, + else => unreachable, + } + } + pub fn exp(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value { if (float_type.zigTypeTag() == .Vector) { const result_data = try arena.alloc(Value, float_type.vectorLen()); @@ -4540,16 +4536,10 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @exp(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt exp for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @exp(f)); }, 128 => { - if (true) { - @panic("TODO implement compiler_rt exp for f128"); - } const f = val.toFloat(f128); return Value.Tag.float_128.create(arena, @exp(f)); }, @@ -4583,16 +4573,10 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @exp2(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt exp2 for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @exp2(f)); }, 128 => { - if (true) { - @panic("TODO implement compiler_rt exp2 for f128"); - } const f = val.toFloat(f128); return Value.Tag.float_128.create(arena, @exp2(f)); }, @@ -4626,16 +4610,10 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @log(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt log for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @log(f)); }, 128 => { - if (true) { - @panic("TODO implement compiler_rt log for f128"); - } const f = val.toFloat(f128); return Value.Tag.float_128.create(arena, @log(f)); }, @@ -4669,16 +4647,10 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @log2(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt log2 for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @log2(f)); }, 128 => { - if (true) { - @panic("TODO implement compiler_rt log2 for f128"); - } const f = val.toFloat(f128); return Value.Tag.float_128.create(arena, @log2(f)); }, @@ -4712,16 +4684,10 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @log10(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt log10 for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @log10(f)); }, 128 => { - if (true) { - @panic("TODO implement compiler_rt log10 for f128"); - } const f = val.toFloat(f128); return Value.Tag.float_128.create(arena, @log10(f)); }, @@ -4755,9 +4721,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @fabs(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt fabs for f80 (__fabsx)"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @fabs(f)); }, @@ -4795,9 +4758,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @floor(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt floor for f80 (__floorx)"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @floor(f)); }, @@ -4835,9 +4795,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @ceil(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt ceil for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @ceil(f)); }, @@ -4875,9 +4832,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @round(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt round for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @round(f)); }, @@ -4915,9 +4869,6 @@ pub const Value = extern union { return Value.Tag.float_64.create(arena, @trunc(f)); }, 80 => { - if (true) { - @panic("TODO implement compiler_rt trunc for f80"); - } const f = val.toFloat(f80); return Value.Tag.float_80.create(arena, @trunc(f)); }, |
