1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdio.h>
2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <assert.h>
3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdint.h>
4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <inttypes.h>
5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "opcodes.h"
6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Test "convert from fixed" with universally available rounding modes.
8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Rounding mode is provided via FPC. */
9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvolatile int32_t i32;
11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvolatile int64_t i64;
12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst char *
14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovrtext(unsigned fpc_round)
15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (fpc_round) {
17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 0: return "[-> near]";
18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 1: return "[-> zero]";
19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 2: return "[-> +inf]";
20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 3: return "[-> -inf]";
21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(0);
23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid
26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovset_rounding_mode(unsigned mode)
27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("setting FPC rounding mode to %s\n", rtext(mode));
29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   register unsigned r asm("1") = mode;
30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   __asm__ volatile ( SFPC(1) : : "d"(r) );
31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid cefbr(unsigned mode)
34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   set_rounding_mode(mode);
36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   float out;
38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   __asm__ volatile("cefbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i32));
40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("cefbr:  %"PRId32" -> %f\n", i32, out);
41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid cegbr(unsigned mode)
44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   set_rounding_mode(mode);
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   float out;
48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   __asm__ volatile("cegbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("cegbr:  %"PRId64" -> %f\n", i64, out);
51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid cdgbr(unsigned mode)
54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   set_rounding_mode(mode);
56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   double out;
58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   __asm__ volatile("cdgbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("cegbr:  %"PRId64" -> %f\n", i64, out);
61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint main()
65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   int mode;
67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* i32 -> f32 */
69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i32 = INT32_MAX;
70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   for (mode = 0; mode <= 3; ++mode) cefbr(mode);
71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n");
72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i32 = INT32_MIN;
73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   for (mode = 0; mode <= 3; ++mode) cefbr(mode);
74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n");
75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* i64 -> f32 */
77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i64 = INT64_MAX;
78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   for (mode = 0; mode <= 3; ++mode) cegbr(mode);
79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n");
80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i64 = INT64_MIN;
81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   for (mode = 0; mode <= 3; ++mode) cegbr(mode);
82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n");
83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* i64 -> f64 */
85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i64 = INT64_MAX;
86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n");
88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i64 = INT64_MIN;
89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n");
91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return 0;
93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
94