1ee5fa1f2SLuke Ireland #include "flang/Decimal/decimal.h"
28670e499SCaroline Concatto #include "llvm/Support/raw_ostream.h"
3ee5fa1f2SLuke Ireland #include <cinttypes>
4ee5fa1f2SLuke Ireland #include <cstdio>
5ee5fa1f2SLuke Ireland #include <cstring>
6ee5fa1f2SLuke Ireland
7ee5fa1f2SLuke Ireland static constexpr int incr{1}; // steps through all values
8ee5fa1f2SLuke Ireland static constexpr bool doNegative{true};
9ee5fa1f2SLuke Ireland static constexpr bool doMinimize{true};
10ee5fa1f2SLuke Ireland
11ee5fa1f2SLuke Ireland using namespace Fortran::decimal;
12ee5fa1f2SLuke Ireland
13ee5fa1f2SLuke Ireland static std::uint64_t tests{0};
14ee5fa1f2SLuke Ireland static std::uint64_t fails{0};
15ee5fa1f2SLuke Ireland
16ee5fa1f2SLuke Ireland union u {
17ee5fa1f2SLuke Ireland float x;
18ee5fa1f2SLuke Ireland std::uint32_t u;
19ee5fa1f2SLuke Ireland };
20ee5fa1f2SLuke Ireland
failed(float x)218670e499SCaroline Concatto llvm::raw_ostream &failed(float x) {
22ee5fa1f2SLuke Ireland ++fails;
23ee5fa1f2SLuke Ireland union u u;
24ee5fa1f2SLuke Ireland u.x = x;
258670e499SCaroline Concatto llvm::outs() << "FAIL: 0x";
268670e499SCaroline Concatto return llvm::outs().write_hex(u.u);
27ee5fa1f2SLuke Ireland }
28ee5fa1f2SLuke Ireland
testReadback(float x,int flags)29ee5fa1f2SLuke Ireland void testReadback(float x, int flags) {
30ee5fa1f2SLuke Ireland char buffer[1024];
31ee5fa1f2SLuke Ireland union u u;
32ee5fa1f2SLuke Ireland u.x = x;
33ee5fa1f2SLuke Ireland if (!(tests & 0x3fffff)) {
348670e499SCaroline Concatto llvm::errs() << "\n0x";
358670e499SCaroline Concatto llvm::errs().write_hex(u.u) << ' ';
36ee5fa1f2SLuke Ireland } else if (!(tests & 0xffff)) {
378670e499SCaroline Concatto llvm::errs() << '.';
38ee5fa1f2SLuke Ireland }
39ee5fa1f2SLuke Ireland ++tests;
40ee5fa1f2SLuke Ireland auto result{ConvertFloatToDecimal(buffer, sizeof buffer,
41ee5fa1f2SLuke Ireland static_cast<enum DecimalConversionFlags>(flags), 1024, RoundNearest, x)};
42ee5fa1f2SLuke Ireland if (result.str == nullptr) {
43ee5fa1f2SLuke Ireland failed(x) << ' ' << flags << ": no result str\n";
44ee5fa1f2SLuke Ireland } else {
45ee5fa1f2SLuke Ireland float y{0};
46ee5fa1f2SLuke Ireland char *q{const_cast<char *>(result.str)};
47ee5fa1f2SLuke Ireland if ((*q >= '0' && *q <= '9') ||
48ee5fa1f2SLuke Ireland ((*q == '-' || *q == '+') && q[1] >= '0' && q[1] <= '9')) {
49ee5fa1f2SLuke Ireland int expo{result.decimalExponent};
50ee5fa1f2SLuke Ireland expo -= result.length;
51ee5fa1f2SLuke Ireland if (*q == '-' || *q == '+') {
52ee5fa1f2SLuke Ireland ++expo;
53ee5fa1f2SLuke Ireland }
54*ecd69175SPeter Klausler std::snprintf(q + result.length,
55*ecd69175SPeter Klausler buffer + sizeof buffer - (q + result.length), "e%d", expo);
56ee5fa1f2SLuke Ireland }
57ee5fa1f2SLuke Ireland const char *p{q};
58ee5fa1f2SLuke Ireland auto rflags{ConvertDecimalToFloat(&p, &y, RoundNearest)};
59ee5fa1f2SLuke Ireland if (!(x == x)) {
60ee5fa1f2SLuke Ireland if (y == y || *p != '\0' || (rflags & Invalid)) {
61ee5fa1f2SLuke Ireland u.x = y;
628670e499SCaroline Concatto failed(x) << " (NaN) " << flags << ": -> '" << result.str << "' -> 0x";
638670e499SCaroline Concatto failed(x).write_hex(u.u) << " '" << p << "' " << rflags << '\n';
64ee5fa1f2SLuke Ireland }
65ee5fa1f2SLuke Ireland } else if (x != y || *p != '\0' || (rflags & Invalid)) {
66ee5fa1f2SLuke Ireland u.x = y;
678670e499SCaroline Concatto failed(x) << ' ' << flags << ": -> '" << result.str << "' -> 0x";
688670e499SCaroline Concatto failed(x).write_hex(u.u) << " '" << p << "' " << rflags << '\n';
69ee5fa1f2SLuke Ireland }
70ee5fa1f2SLuke Ireland }
71ee5fa1f2SLuke Ireland }
72ee5fa1f2SLuke Ireland
main()73ee5fa1f2SLuke Ireland int main() {
74ee5fa1f2SLuke Ireland union u u;
75ee5fa1f2SLuke Ireland for (u.u = 0; u.u < 0x7f800010; u.u += incr) {
76ee5fa1f2SLuke Ireland testReadback(u.x, 0);
77ee5fa1f2SLuke Ireland if constexpr (doNegative) {
78ee5fa1f2SLuke Ireland testReadback(-u.x, 0);
79ee5fa1f2SLuke Ireland }
80ee5fa1f2SLuke Ireland if constexpr (doMinimize) {
81ee5fa1f2SLuke Ireland testReadback(u.x, Minimize);
82ee5fa1f2SLuke Ireland if constexpr (doNegative) {
83ee5fa1f2SLuke Ireland testReadback(-u.x, Minimize);
84ee5fa1f2SLuke Ireland }
85ee5fa1f2SLuke Ireland }
86ee5fa1f2SLuke Ireland }
878670e499SCaroline Concatto llvm::outs() << '\n' << tests << " tests run, " << fails << " tests failed\n";
88ee5fa1f2SLuke Ireland return fails > 0;
89ee5fa1f2SLuke Ireland }
90