1#include <stdio.h>
2#include <assert.h>
3#include <stdint.h>
4#include <inttypes.h>
5#include "opcodes.h"
6
7/* Test "convert from fixed" with universally available rounding modes.
8   Rounding mode is provided via FPC. */
9
10volatile int32_t i32;
11volatile int64_t i64;
12
13const char *
14rtext(unsigned fpc_round)
15{
16   switch (fpc_round) {
17   case 0: return "[-> near]";
18   case 1: return "[-> zero]";
19   case 2: return "[-> +inf]";
20   case 3: return "[-> -inf]";
21   }
22   assert(0);
23}
24
25void
26set_rounding_mode(unsigned mode)
27{
28   printf("setting FPC rounding mode to %s\n", rtext(mode));
29   register unsigned r asm("1") = mode;
30   __asm__ volatile ( SFPC(1) : : "d"(r) );
31}
32
33void cefbr(unsigned mode)
34{
35   set_rounding_mode(mode);
36
37   float out;
38
39   __asm__ volatile("cefbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i32));
40   printf("cefbr:  %"PRId32" -> %f\n", i32, out);
41}
42
43void cegbr(unsigned mode)
44{
45   set_rounding_mode(mode);
46
47   float out;
48
49   __asm__ volatile("cegbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
50   printf("cegbr:  %"PRId64" -> %f\n", i64, out);
51}
52
53void cdgbr(unsigned mode)
54{
55   set_rounding_mode(mode);
56
57   double out;
58
59   __asm__ volatile("cdgbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
60   printf("cegbr:  %"PRId64" -> %f\n", i64, out);
61}
62
63
64int main()
65{
66   int mode;
67
68   /* i32 -> f32 */
69   i32 = INT32_MAX;
70   for (mode = 0; mode <= 3; ++mode) cefbr(mode);
71   printf("\n");
72   i32 = INT32_MIN;
73   for (mode = 0; mode <= 3; ++mode) cefbr(mode);
74   printf("\n");
75
76   /* i64 -> f32 */
77   i64 = INT64_MAX;
78   for (mode = 0; mode <= 3; ++mode) cegbr(mode);
79   printf("\n");
80   i64 = INT64_MIN;
81   for (mode = 0; mode <= 3; ++mode) cegbr(mode);
82   printf("\n");
83
84   /* i64 -> f64 */
85   i64 = INT64_MAX;
86   for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
87   printf("\n");
88   i64 = INT64_MIN;
89   for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
90   printf("\n");
91
92   return 0;
93}
94