• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
10 volatile int32_t i32;
11 volatile int64_t i64;
12 
13 const char *
rtext(unsigned fpc_round)14 rtext(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 
25 void
set_rounding_mode(unsigned mode)26 set_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 
cefbr(unsigned mode)33 void 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 
cegbr(unsigned mode)43 void 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 
cdgbr(unsigned mode)53 void 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 
main()64 int 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