1*6dc29354SIlya Leoshkevich /*
2*6dc29354SIlya Leoshkevich * Helpers for floating-point tests.
3*6dc29354SIlya Leoshkevich *
4*6dc29354SIlya Leoshkevich * SPDX-License-Identifier: GPL-2.0-or-later
5*6dc29354SIlya Leoshkevich */
6*6dc29354SIlya Leoshkevich #ifndef FLOAT_H
7*6dc29354SIlya Leoshkevich #define FLOAT_H
8*6dc29354SIlya Leoshkevich
9*6dc29354SIlya Leoshkevich /*
10*6dc29354SIlya Leoshkevich * Floating-point value classes.
11*6dc29354SIlya Leoshkevich */
12*6dc29354SIlya Leoshkevich #define N_FORMATS 3
13*6dc29354SIlya Leoshkevich #define CLASS_MINUS_INF 0
14*6dc29354SIlya Leoshkevich #define CLASS_MINUS_FN 1
15*6dc29354SIlya Leoshkevich #define CLASS_MINUS_ZERO 2
16*6dc29354SIlya Leoshkevich #define CLASS_PLUS_ZERO 3
17*6dc29354SIlya Leoshkevich #define CLASS_PLUS_FN 4
18*6dc29354SIlya Leoshkevich #define CLASS_PLUS_INF 5
19*6dc29354SIlya Leoshkevich #define CLASS_QNAN 6
20*6dc29354SIlya Leoshkevich #define CLASS_SNAN 7
21*6dc29354SIlya Leoshkevich #define N_SIGNED_CLASSES 8
22*6dc29354SIlya Leoshkevich static const size_t float_sizes[N_FORMATS] = {
23*6dc29354SIlya Leoshkevich /* M4 == 2: short */ 4,
24*6dc29354SIlya Leoshkevich /* M4 == 3: long */ 8,
25*6dc29354SIlya Leoshkevich /* M4 == 4: extended */ 16,
26*6dc29354SIlya Leoshkevich };
27*6dc29354SIlya Leoshkevich static const size_t e_bits[N_FORMATS] = {
28*6dc29354SIlya Leoshkevich /* M4 == 2: short */ 8,
29*6dc29354SIlya Leoshkevich /* M4 == 3: long */ 11,
30*6dc29354SIlya Leoshkevich /* M4 == 4: extended */ 15,
31*6dc29354SIlya Leoshkevich };
32*6dc29354SIlya Leoshkevich struct float_class {
33*6dc29354SIlya Leoshkevich size_t n;
34*6dc29354SIlya Leoshkevich unsigned char v[2][16];
35*6dc29354SIlya Leoshkevich };
36*6dc29354SIlya Leoshkevich static const struct float_class signed_floats[N_FORMATS][N_SIGNED_CLASSES] = {
37*6dc29354SIlya Leoshkevich /* M4 == 2: short */
38*6dc29354SIlya Leoshkevich {
39*6dc29354SIlya Leoshkevich /* -inf */ {1, {{0xff, 0x80, 0x00, 0x00}}},
40*6dc29354SIlya Leoshkevich /* -Fn */ {2, {{0xc2, 0x28, 0x00, 0x00},
41*6dc29354SIlya Leoshkevich {0xc2, 0x29, 0x00, 0x00}}},
42*6dc29354SIlya Leoshkevich /* -0 */ {1, {{0x80, 0x00, 0x00, 0x00}}},
43*6dc29354SIlya Leoshkevich /* +0 */ {1, {{0x00, 0x00, 0x00, 0x00}}},
44*6dc29354SIlya Leoshkevich /* +Fn */ {2, {{0x42, 0x28, 0x00, 0x00},
45*6dc29354SIlya Leoshkevich {0x42, 0x2a, 0x00, 0x00}}},
46*6dc29354SIlya Leoshkevich /* +inf */ {1, {{0x7f, 0x80, 0x00, 0x00}}},
47*6dc29354SIlya Leoshkevich /* QNaN */ {2, {{0x7f, 0xff, 0xff, 0xff},
48*6dc29354SIlya Leoshkevich {0x7f, 0xff, 0xff, 0xfe}}},
49*6dc29354SIlya Leoshkevich /* SNaN */ {2, {{0x7f, 0xbf, 0xff, 0xff},
50*6dc29354SIlya Leoshkevich {0x7f, 0xbf, 0xff, 0xfd}}},
51*6dc29354SIlya Leoshkevich },
52*6dc29354SIlya Leoshkevich
53*6dc29354SIlya Leoshkevich /* M4 == 3: long */
54*6dc29354SIlya Leoshkevich {
55*6dc29354SIlya Leoshkevich /* -inf */ {1, {{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
56*6dc29354SIlya Leoshkevich /* -Fn */ {2, {{0xc0, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
57*6dc29354SIlya Leoshkevich {0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
58*6dc29354SIlya Leoshkevich /* -0 */ {1, {{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
59*6dc29354SIlya Leoshkevich /* +0 */ {1, {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
60*6dc29354SIlya Leoshkevich /* +Fn */ {2, {{0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
61*6dc29354SIlya Leoshkevich {0x40, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
62*6dc29354SIlya Leoshkevich /* +inf */ {1, {{0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
63*6dc29354SIlya Leoshkevich /* QNaN */ {2, {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
64*6dc29354SIlya Leoshkevich {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}},
65*6dc29354SIlya Leoshkevich /* SNaN */ {2, {{0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
66*6dc29354SIlya Leoshkevich {0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd}}},
67*6dc29354SIlya Leoshkevich },
68*6dc29354SIlya Leoshkevich
69*6dc29354SIlya Leoshkevich /* M4 == 4: extended */
70*6dc29354SIlya Leoshkevich {
71*6dc29354SIlya Leoshkevich /* -inf */ {1, {{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
72*6dc29354SIlya Leoshkevich /* -Fn */ {2, {{0xc0, 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
73*6dc29354SIlya Leoshkevich {0xc0, 0x04, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
74*6dc29354SIlya Leoshkevich /* -0 */ {1, {{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
75*6dc29354SIlya Leoshkevich /* +0 */ {1, {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
76*6dc29354SIlya Leoshkevich /* +Fn */ {2, {{0x40, 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
77*6dc29354SIlya Leoshkevich {0x40, 0x04, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
78*6dc29354SIlya Leoshkevich /* +inf */ {1, {{0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
79*6dc29354SIlya Leoshkevich /* QNaN */ {2, {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
80*6dc29354SIlya Leoshkevich {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}},
81*6dc29354SIlya Leoshkevich /* SNaN */ {2, {{0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
82*6dc29354SIlya Leoshkevich {0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd}}},
83*6dc29354SIlya Leoshkevich },
84*6dc29354SIlya Leoshkevich };
85*6dc29354SIlya Leoshkevich static const unsigned char default_nans[N_FORMATS][16] = {
86*6dc29354SIlya Leoshkevich /* M4 == 2: short */ {0x7f, 0xc0, 0x00, 0x00},
87*6dc29354SIlya Leoshkevich /* M4 == 3: long */ {0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
88*6dc29354SIlya Leoshkevich /* M4 == 4: extended */ {0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
89*6dc29354SIlya Leoshkevich };
90*6dc29354SIlya Leoshkevich
dump_v(FILE * f,const void * v,size_t n)91*6dc29354SIlya Leoshkevich static void dump_v(FILE *f, const void *v, size_t n)
92*6dc29354SIlya Leoshkevich {
93*6dc29354SIlya Leoshkevich for (int i = 0; i < n; i++) {
94*6dc29354SIlya Leoshkevich fprintf(f, "%02x", ((const unsigned char *)v)[i]);
95*6dc29354SIlya Leoshkevich }
96*6dc29354SIlya Leoshkevich }
97*6dc29354SIlya Leoshkevich
snan_to_qnan(char * v,int fmt)98*6dc29354SIlya Leoshkevich static void snan_to_qnan(char *v, int fmt)
99*6dc29354SIlya Leoshkevich {
100*6dc29354SIlya Leoshkevich size_t bit = 1 + e_bits[fmt];
101*6dc29354SIlya Leoshkevich v[bit / 8] |= 1 << (7 - (bit % 8));
102*6dc29354SIlya Leoshkevich }
103*6dc29354SIlya Leoshkevich
104*6dc29354SIlya Leoshkevich #endif
105