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
21unsigned
22get_rounding_mode(void)
23{
24   unsigned fpc;
25
26   __asm__ volatile ("stfpc  %0\n\t" : "=m"(fpc));
27
28   return fpc & 0x7;
29}
30
31int 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