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