zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

mulf3_test.zig (6670B) - Raw


      1 // Ported from:
      2 //
      3 // https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/test/builtins/Unit/multf3_test.c
      4 
      5 const std = @import("std");
      6 const math = std.math;
      7 const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);
      8 const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64);
      9 
     10 const __multf3 = @import("multf3.zig").__multf3;
     11 const __mulxf3 = @import("mulxf3.zig").__mulxf3;
     12 const __muldf3 = @import("muldf3.zig").__muldf3;
     13 const __mulsf3 = @import("mulsf3.zig").__mulsf3;
     14 
     15 // return true if equal
     16 // use two 64-bit integers instead of one 128-bit integer
     17 // because 128-bit integer constant can't be assigned directly
     18 fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
     19     const rep: u128 = @bitCast(result);
     20     const hi: u64 = @intCast(rep >> 64);
     21     const lo: u64 = @truncate(rep);
     22 
     23     if (hi == expectedHi and lo == expectedLo) {
     24         return true;
     25     }
     26     // test other possible NaN representation(signal NaN)
     27     if (expectedHi == 0x7fff800000000000 and expectedLo == 0x0) {
     28         if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
     29             ((hi & 0xffffffffffff) > 0 or lo > 0))
     30         {
     31             return true;
     32         }
     33     }
     34     return false;
     35 }
     36 
     37 fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
     38     const x = __multf3(a, b);
     39 
     40     if (compareResultLD(x, expected_hi, expected_lo))
     41         return;
     42 
     43     @panic("__multf3 test failure");
     44 }
     45 
     46 fn makeNaN128(rand: u64) f128 {
     47     const int_result = @as(u128, 0x7fff000000000000 | (rand & 0xffffffffffff)) << 64;
     48     return @bitCast(int_result);
     49 }
     50 test "multf3" {
     51     // qNaN * any = qNaN
     52     try test__multf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
     53 
     54     // NaN * any = NaN
     55     const a = makeNaN128(0x800030000000);
     56     try test__multf3(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
     57     // inf * any = inf
     58     try test__multf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);
     59 
     60     // any * any
     61     try test__multf3(
     62         @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))),
     63         @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))),
     64         0x400423e7f9e3c9fc,
     65         0xd906c2c2a85777c4,
     66     );
     67 
     68     try test__multf3(
     69         @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))),
     70         @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))),
     71         0x3fc52a163c6223fc,
     72         0xc94c4bf0430768b4,
     73     );
     74 
     75     try test__multf3(
     76         0x1.234425696abcad34a35eeffefdcbap+456,
     77         0x451.ed98d76e5d46e5f24323dff21ffp+600,
     78         0x44293a91de5e0e94,
     79         0xe8ed17cc2cdf64ac,
     80     );
     81 
     82     try test__multf3(
     83         @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))),
     84         @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))),
     85         0x3d4f37c1a3137cae,
     86         0xfc6807048bc2836a,
     87     );
     88 
     89     try test__multf3(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0);
     90 
     91     // Denormal operands.
     92     try test__multf3(
     93         0x0.0000000000000000000000000001p-16382,
     94         0x1p16383,
     95         0x3f90000000000000,
     96         0x0,
     97     );
     98     try test__multf3(
     99         0x1p16383,
    100         0x0.0000000000000000000000000001p-16382,
    101         0x3f90000000000000,
    102         0x0,
    103     );
    104 
    105     try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002);
    106     try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003);
    107     try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002);
    108 }
    109 
    110 const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));
    111 
    112 fn test__mulxf3(a: f80, b: f80, expected: u80) !void {
    113     const x = __mulxf3(a, b);
    114     const rep: u80 = @bitCast(x);
    115 
    116     if (rep == expected)
    117         return;
    118 
    119     if (math.isNan(@as(f80, @bitCast(expected))) and math.isNan(x))
    120         return; // We don't currently test NaN payload propagation
    121 
    122     return error.TestFailed;
    123 }
    124 
    125 test "mulxf3" {
    126     // NaN * any = NaN
    127     try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
    128     try test__mulxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
    129 
    130     // any * NaN = NaN
    131     try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80)));
    132     try test__mulxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
    133 
    134     // NaN * inf = NaN
    135     try test__mulxf3(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80)));
    136 
    137     // inf * NaN = NaN
    138     try test__mulxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80)));
    139 
    140     // inf * inf = inf
    141     try test__mulxf3(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80))));
    142 
    143     // inf * -inf = -inf
    144     try test__mulxf3(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80))));
    145 
    146     // -inf + inf = -inf
    147     try test__mulxf3(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80))));
    148 
    149     // inf * any = inf
    150     try test__mulxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80))));
    151 
    152     // any * inf = inf
    153     try test__mulxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80))));
    154 
    155     // any * any
    156     try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800);
    157     try test__mulxf3(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact
    158 
    159     try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact
    160     try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down
    161     try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even
    162     try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up
    163     try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact
    164 
    165     try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even
    166     try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up
    167     try test__mulxf3(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal
    168     try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal
    169     try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal
    170 }