1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
/* { dg-do run { target { powerpc*-*-linux* } } } */
/* { dg-require-effective-target ppc_float128_sw } */
/* { dg-require-effective-target vsx_hw } */
/* { dg-options "-mvsx -O2" } */
/* This is the same as test float128-1.c, using the _Float128 keyword instead
of __float128, and not using -mfloat128. */
#ifdef DEBUG
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>
#endif
#if !defined(__FLOAT128__) || !defined(_ARCH_PPC)
static _Float128
pass_through (_Float128 x)
{
return x;
}
_Float128 (*no_optimize) (_Float128) = pass_through;
#endif
#ifdef DEBUG
__attribute__((__noinline__))
static void
print_f128 (_Float128 x)
{
unsigned sign;
unsigned exponent;
uint64_t mantissa1;
uint64_t mantissa2;
uint64_t upper;
uint64_t lower;
#if defined(_ARCH_PPC) && defined(__BIG_ENDIAN__)
struct ieee128 {
uint64_t upper;
uint64_t lower;
};
#elif (defined(_ARCH_PPC) && defined(__LITTLE_ENDIAN__)) || defined(__x86_64__)
struct ieee128 {
uint64_t lower;
uint64_t upper;
};
#else
#error "Unknown system"
#endif
union {
_Float128 f128;
struct ieee128 s128;
} u;
u.f128 = x;
upper = u.s128.upper;
lower = u.s128.lower;
sign = (unsigned)((upper >> 63) & 1);
exponent = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1));
mantissa1 = (upper & ((((uint64_t)1) << 48) - 1));
mantissa2 = lower;
printf ("%c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64,
sign ? '-' : '+',
exponent,
mantissa1,
mantissa2);
}
#endif
__attribute__((__noinline__))
static void
do_test (_Float128 expected, _Float128 got, const char *name)
{
int equal_p = (expected == got);
#ifdef DEBUG
printf ("Test %s, expected: ", name);
print_f128 (expected);
printf (" %5g, got: ", (double) expected);
print_f128 (got);
printf (" %5g, result %s\n",
(double) got,
(equal_p) ? "equal" : "not equal");
#endif
if (!equal_p)
__builtin_abort ();
}
int
main (void)
{
_Float128 one = 1.0f128;
_Float128 two = 2.0f128;
_Float128 three = 3.0f128;
_Float128 four = 4.0f128;
_Float128 five = 5.0f128;
_Float128 add_result = (1.0f128 + 2.0f128);
_Float128 mul_result = ((1.0f128 + 2.0f128) * 3.0f128);
_Float128 div_result = (((1.0f128 + 2.0f128) * 3.0f128) / 4.0f128);
_Float128 sub_result = ((((1.0f128 + 2.0f128) * 3.0f128) / 4.0f128)
- 5.0f128);
_Float128 neg_result = - sub_result;
_Float128 add_xresult;
_Float128 mul_xresult;
_Float128 div_xresult;
_Float128 sub_xresult;
_Float128 neg_xresult;
#if defined(__FLOAT128__) && defined(_ARCH_PPC)
__asm__ (" #prevent constant folding, %x0" : "+wa" (one));
__asm__ (" #prevent constant folding, %x0" : "+wa" (two));
__asm__ (" #prevent constant folding, %x0" : "+wa" (three));
__asm__ (" #prevent constant folding, %x0" : "+wa" (four));
__asm__ (" #prevent constant folding, %x0" : "+wa" (five));
#else
one = no_optimize (one);
two = no_optimize (two);
three = no_optimize (three);
four = no_optimize (four);
five = no_optimize (five);
#endif
add_xresult = (one + two);
do_test (add_result, add_xresult, "add");
mul_xresult = add_xresult * three;
do_test (mul_result, mul_xresult, "mul");
div_xresult = mul_xresult / four;
do_test (div_result, div_xresult, "div");
sub_xresult = div_xresult - five;
do_test (sub_result, sub_xresult, "sub");
neg_xresult = - sub_xresult;
do_test (neg_result, neg_xresult, "neg");
#ifdef DEBUG
printf ("Passed\n");
#endif
return 0;
}
|