master
  1// Ported from:
  2//
  3// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/test/builtins/Unit/multf3_test.c
  4
  5const std = @import("std");
  6const math = std.math;
  7const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);
  8const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64);
  9
 10const __multf3 = @import("multf3.zig").__multf3;
 11const __mulxf3 = @import("mulxf3.zig").__mulxf3;
 12const __muldf3 = @import("muldf3.zig").__muldf3;
 13const __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
 18fn 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
 37fn 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
 46fn makeNaN128(rand: u64) f128 {
 47    const int_result = @as(u128, 0x7fff000000000000 | (rand & 0xffffffffffff)) << 64;
 48    return @bitCast(int_result);
 49}
 50test "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
110const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));
111
112fn 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
125test "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}