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