Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ziglang/zig
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a3ab4325fd05
Choose a base ref
...
head repository: ziglang/zig
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 887c97742f86
Choose a head ref
  • 10 commits
  • 20 files changed
  • 1 contributor

Commits on Jun 30, 2018

  1. Copy the full SHA
    379950f View commit details
  2. compiler_rt: Add floatuntisf

    tiehuis committed Jun 30, 2018
    Copy the full SHA
    c32b2e4 View commit details
  3. Copy the full SHA
    61ebfe6 View commit details
  4. compiler_rt: Add floatuntitf

    tiehuis committed Jun 30, 2018
    Copy the full SHA
    cb7bdc2 View commit details
  5. Copy the full SHA
    e19fc4a View commit details
  6. Copy the full SHA
    53fef94 View commit details
  7. Copy the full SHA
    814a34f View commit details
  8. Copy the full SHA
    9f48b2a View commit details
  9. Copy the full SHA
    951512f View commit details
  10. Copy the full SHA
    887c977 View commit details
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -585,7 +585,14 @@ set(ZIG_STD_FILES
"special/compiler_rt/fixunstfdi.zig"
"special/compiler_rt/fixunstfsi.zig"
"special/compiler_rt/fixunstfti.zig"
"special/compiler_rt/floatunditf.zig"
"special/compiler_rt/floatunsitf.zig"
"special/compiler_rt/floatuntidf.zig"
"special/compiler_rt/floatuntisf.zig"
"special/compiler_rt/floatuntitf.zig"
"special/compiler_rt/floattidf.zig"
"special/compiler_rt/floattisf.zig"
"special/compiler_rt/floattitf.zig"
"special/compiler_rt/muloti4.zig"
"special/compiler_rt/index.zig"
"special/compiler_rt/truncXfYf2.zig"
2 changes: 1 addition & 1 deletion std/fmt/index.zig
Original file line number Diff line number Diff line change
@@ -327,7 +327,7 @@ pub fn formatFloatScientific(
comptime Errors: type,
output: fn (@typeOf(context), []const u8) Errors!void,
) Errors!void {
var x = f64(value);
var x = @floatCast(f64, value);

// Errol doesn't handle these special cases.
if (math.signbit(x)) {
69 changes: 69 additions & 0 deletions std/special/compiler_rt/floattidf.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const builtin = @import("builtin");
const is_test = builtin.is_test;

const DBL_MANT_DIG = 53;

pub extern fn __floattidf(arg: i128) f64 {
@setRuntimeSafety(is_test);

if (arg == 0)
return 0.0;

var ai = arg;
const N: u32 = 128;
const si = ai >> @intCast(u7, (N - 1));
ai = ((ai ^ si) -% si);
var a = @bitCast(u128, ai);

const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
var e: i32 = sd - 1; // exponent
if (sd > DBL_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit DBL_MANT_DIG-1 bits to the right of 1
// Q = bit DBL_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
DBL_MANT_DIG + 1 => {
a <<= 1;
},
DBL_MANT_DIG + 2 => {},
else => {
const shift1_amt = @intCast(i32, sd - (DBL_MANT_DIG + 2));
const shift1_amt_u7 = @intCast(u7, shift1_amt);

const shift2_amt = @intCast(i32, N + (DBL_MANT_DIG + 2)) - sd;
const shift2_amt_u7 = @intCast(u7, shift2_amt);

a = (a >> shift1_amt_u7) | @boolToInt((a & (@intCast(u128, @maxValue(u128)) >> shift2_amt_u7)) != 0);
},
}
// finish
a |= @boolToInt((a & 4) != 0); // Or P into R
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
if ((a & (u128(1) << DBL_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
// a is now rounded to DBL_MANT_DIG bits
} else {
a <<= @intCast(u7, DBL_MANT_DIG - sd);
// a is now rounded to DBL_MANT_DIG bits
}

const s = @bitCast(u128, arg) >> (128 - 32);
const high: u64 = (@intCast(u64, s) & 0x80000000) | // sign
(@intCast(u32, (e + 1023)) << 20) | // exponent
(@truncate(u32, a >> 32) & 0x000fffff); // mantissa-high
const low: u64 = @truncate(u32, a); // mantissa-low

return @bitCast(f64, low | (high << 32));
}

test "import floattidf" {
_ = @import("floattidf_test.zig");
}
84 changes: 84 additions & 0 deletions std/special/compiler_rt/floattidf_test.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const __floattidf = @import("floattidf.zig").__floattidf;
const assert = @import("std").debug.assert;

fn test__floattidf(a: i128, expected: f64) void {
const x = __floattidf(a);
assert(x == expected);
}

test "floattidf" {
test__floattidf(0, 0.0);

test__floattidf(1, 1.0);
test__floattidf(2, 2.0);
test__floattidf(20, 20.0);
test__floattidf(-1, -1.0);
test__floattidf(-2, -2.0);
test__floattidf(-20, -20.0);

test__floattidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
test__floattidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
test__floattidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
test__floattidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);

test__floattidf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
test__floattidf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
test__floattidf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
test__floattidf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);

test__floattidf(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
test__floattidf(make_ti(0x8000000000000001, 0), -0x1.000000p+127);

test__floattidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);

test__floattidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
test__floattidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
test__floattidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
test__floattidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
test__floattidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);

test__floattidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
test__floattidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
test__floattidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
test__floattidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
test__floattidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);

test__floattidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
test__floattidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
test__floattidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
test__floattidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
test__floattidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
test__floattidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);

test__floattidf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
test__floattidf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
test__floattidf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
test__floattidf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
test__floattidf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
test__floattidf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
}

fn make_ti(high: u64, low: u64) i128 {
var result: u128 = high;
result <<= 64;
result |= low;
return @bitCast(i128, result);
}
69 changes: 69 additions & 0 deletions std/special/compiler_rt/floattisf.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const builtin = @import("builtin");
const is_test = builtin.is_test;

const FLT_MANT_DIG = 24;

pub extern fn __floattisf(arg: i128) f32 {
@setRuntimeSafety(is_test);

if (arg == 0)
return 0.0;

var ai = arg;
const N: u32 = 128;
const si = ai >> @intCast(u7, (N - 1));
ai = ((ai ^ si) -% si);
var a = @bitCast(u128, ai);

const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
var e: i32 = sd - 1; // exponent

if (sd > FLT_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit FLT_MANT_DIG-1 bits to the right of 1
// Q = bit FLT_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
FLT_MANT_DIG + 1 => {
a <<= 1;
},
FLT_MANT_DIG + 2 => {},
else => {
const shift1_amt = @intCast(i32, sd - (FLT_MANT_DIG + 2));
const shift1_amt_u7 = @intCast(u7, shift1_amt);

const shift2_amt = @intCast(i32, N + (FLT_MANT_DIG + 2)) - sd;
const shift2_amt_u7 = @intCast(u7, shift2_amt);

a = (a >> shift1_amt_u7) | @boolToInt((a & (@intCast(u128, @maxValue(u128)) >> shift2_amt_u7)) != 0);
},
}
// finish
a |= @boolToInt((a & 4) != 0); // Or P into R
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
if ((a & (u128(1) << FLT_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
// a is now rounded to FLT_MANT_DIG bits
} else {
a <<= @intCast(u7, FLT_MANT_DIG - sd);
// a is now rounded to FLT_MANT_DIG bits
}

const s = @bitCast(u128, arg) >> (128 - 32);
const r = (@intCast(u32, s) & 0x80000000) | // sign
(@intCast(u32, (e + 127)) << 23) | // exponent
(@truncate(u32, a) & 0x007fffff); // mantissa-high

return @bitCast(f32, r);
}

test "import floattisf" {
_ = @import("floattisf_test.zig");
}
60 changes: 60 additions & 0 deletions std/special/compiler_rt/floattisf_test.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const __floattisf = @import("floattisf.zig").__floattisf;
const assert = @import("std").debug.assert;

fn test__floattisf(a: i128, expected: f32) void {
const x = __floattisf(a);
assert(x == expected);
}

test "floattisf" {
test__floattisf(0, 0.0);

test__floattisf(1, 1.0);
test__floattisf(2, 2.0);
test__floattisf(-1, -1.0);
test__floattisf(-2, -2.0);

test__floattisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
test__floattisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);

test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62);
test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62);

test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63);
test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63);

test__floattisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);

test__floattisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);
test__floattisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);
test__floattisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
test__floattisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);
test__floattisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);

test__floattisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);
test__floattisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);
test__floattisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
test__floattisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);
test__floattisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);

test__floattisf(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114);

test__floattisf(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114);
test__floattisf(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114);
test__floattisf(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114);
test__floattisf(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114);
test__floattisf(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114);

test__floattisf(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114);
test__floattisf(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114);
test__floattisf(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114);
test__floattisf(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114);
test__floattisf(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114);
}

fn make_ti(high: u64, low: u64) i128 {
var result: u128 = high;
result <<= 64;
result |= low;
return @bitCast(i128, result);
}
69 changes: 69 additions & 0 deletions std/special/compiler_rt/floattitf.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const builtin = @import("builtin");
const is_test = builtin.is_test;

const LDBL_MANT_DIG = 113;

pub extern fn __floattitf(arg: i128) f128 {
@setRuntimeSafety(is_test);

if (arg == 0)
return 0.0;

var ai = arg;
const N: u32 = 128;
const si = ai >> @intCast(u7, (N - 1));
ai = ((ai ^ si) -% si);
var a = @bitCast(u128, ai);

const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
var e: i32 = sd - 1; // exponent
if (sd > LDBL_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit LDBL_MANT_DIG-1 bits to the right of 1
// Q = bit LDBL_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
LDBL_MANT_DIG + 1 => {
a <<= 1;
},
LDBL_MANT_DIG + 2 => {},
else => {
const shift1_amt = @intCast(i32, sd - (LDBL_MANT_DIG + 2));
const shift1_amt_u7 = @intCast(u7, shift1_amt);

const shift2_amt = @intCast(i32, N + (LDBL_MANT_DIG + 2)) - sd;
const shift2_amt_u7 = @intCast(u7, shift2_amt);

a = (a >> shift1_amt_u7) | @boolToInt((a & (@intCast(u128, @maxValue(u128)) >> shift2_amt_u7)) != 0);
},
}
// finish
a |= @boolToInt((a & 4) != 0); // Or P into R
a += 1; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
if ((a & (u128(1) << LDBL_MANT_DIG)) != 0) {
a >>= 1;
e += 1;
}
// a is now rounded to LDBL_MANT_DIG bits
} else {
a <<= @intCast(u7, LDBL_MANT_DIG - sd);
// a is now rounded to LDBL_MANT_DIG bits
}

const s = @bitCast(u128, arg) >> (128 - 64);
const high: u128 = (@intCast(u64, s) & 0x8000000000000000) | // sign
(@intCast(u64, (e + 16383)) << 48) | // exponent
(@truncate(u64, a >> 64) & 0x0000ffffffffffff); // mantissa-high
const low = @truncate(u64, a); // mantissa-low

return @bitCast(f128, low | (high << 64));
}

test "import floattitf" {
_ = @import("floattitf_test.zig");
}
Loading