1 #include <assert.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include "opcodes.h"
5 
6 #define srnmb(b,d) \
7    ({ \
8       __asm__ volatile ( "lghi 8," #b "\n\t" \
9                          SRNMB(8,d) \
10                          ::: "8"); \
11    })
12 
13 
14 /* Like srnm above, except it uses r0 as a base register */
15 #define srnmb0(d) \
16    ({ \
17       __asm__ volatile ( SRNMB(0,d) \
18                          ::: "0"); \
19    })
20 
21 unsigned
get_rounding_mode(void)22 get_rounding_mode(void)
23 {
24    unsigned fpc;
25 
26    __asm__ volatile ("stfpc  %0\n\t" : "=m"(fpc));
27 
28    return fpc & 0x7;
29 }
30 
main(void)31 int main(void)
32 {
33    printf("initial rounding mode = %u\n", get_rounding_mode());
34 
35    /* Set basic rounding modes in various ways */
36    srnmb(1,002);  // 1 + 2 = 3
37    printf("rounding mode = %u\n", get_rounding_mode());
38 
39    srnmb(2,000);
40    printf("rounding mode = %u\n", get_rounding_mode());
41 
42    srnmb(0,001);
43    printf("rounding mode = %u\n", get_rounding_mode());
44 
45    srnmb(0,000);
46    printf("rounding mode = %u\n", get_rounding_mode());
47 
48 #if 0
49    // fpext
50    srnmb(7,000);  // -> 7
51    printf("rounding mode = %u\n", get_rounding_mode());
52 
53    srnmb(0,000);  // -> 0
54    printf("rounding mode = %u\n", get_rounding_mode());
55 
56    srnmb(0,007);  // -> 7
57    printf("rounding mode = %u\n", get_rounding_mode());
58 #endif
59 
60    srnmb(0,001);
61    printf("rounding mode = %u\n", get_rounding_mode());
62 
63    srnmb0(004);    // -> emul warning invalid rounding mode
64    printf("rounding mode = %u\n", get_rounding_mode());
65 
66    return 0;
67 }
68