1#include <float.h>
2#include <stdio.h>
3#include "opcodes.h"
4
5
6#define L2F(insn,  initial, target,round)                                \
7({                                                                       \
8   register unsigned long source asm("2") =  initial;                    \
9   register typeof(target) _t asm("f0");                                 \
10   asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source));               \
11   _t;                                                                   \
12})
13
14#define F2L(insn, initial, type, round, cc)                              \
15({                                                                       \
16   register type source asm("f0") =  initial;                            \
17   register unsigned long target asm ("2") = 0;                          \
18   asm volatile(insn(round,0,2,0)                                        \
19                "ipm %1\n\t"                                             \
20                "srl %1,28\n\t"                                          \
21 		:"=d" (target), "=d" (cc) :"f"(source):"cc");            \
22   target;                                                               \
23})
24
25
26#define DO_INSN_L2F32(insn, round)                                       \
27({                                                                       \
28   float f32;                                                            \
29   printf(#insn " %f\n", L2F(insn, 0, f32, round));                      \
30   printf(#insn " %f\n", L2F(insn, 1, f32, round));                      \
31   printf(#insn " %f\n", L2F(insn, 0xffffffffUL, f32, round));           \
32   printf(#insn " %f\n", L2F(insn, 0x80000000UL, f32, round));           \
33   printf(#insn " %f\n", L2F(insn, 0x7fffffffUL, f32, round));           \
34   printf(#insn " %f\n", L2F(insn, 0x100000000UL, f32, round));          \
35   printf(#insn " %f\n", L2F(insn, 0xffffffffffffffffUL, f32, round));   \
36   printf(#insn " %f\n", L2F(insn, 0x8000000000000000UL, f32, round));   \
37   printf(#insn " %f\n", L2F(insn, 0x7fffffffffffffffUL, f32, round));   \
38})
39
40#define DO_INSN_L2F64(insn, round)                                       \
41({                                                                       \
42   double f64;                                                           \
43   printf(#insn " %f\n", L2F(insn, 0, f64, round));                      \
44   printf(#insn " %f\n", L2F(insn, 1, f64, round));                      \
45   printf(#insn " %f\n", L2F(insn, 0xffffffffUL, f64, round));           \
46   printf(#insn " %f\n", L2F(insn, 0x80000000UL, f64, round));           \
47   printf(#insn " %f\n", L2F(insn, 0x7fffffffUL, f64, round));           \
48   printf(#insn " %f\n", L2F(insn, 0x100000000UL, f64, round));          \
49   printf(#insn " %f\n", L2F(insn, 0xffffffffffffffffUL, f64, round));   \
50   printf(#insn " %f\n", L2F(insn, 0x8000000000000000UL, f64, round));   \
51   printf(#insn " %f\n", L2F(insn, 0x7fffffffffffffffUL, f64, round));   \
52})
53
54#define DO_INSN_L2F128(insn, round)                                      \
55({                                                                       \
56   long double f128;                                                     \
57   printf(#insn " %Lf\n", L2F(insn, 0, f128, round));                    \
58   printf(#insn " %Lf\n", L2F(insn, 1, f128, round));                    \
59   printf(#insn " %Lf\n", L2F(insn, 0xffffffffUL, f128, round));         \
60   printf(#insn " %Lf\n", L2F(insn, 0x80000000UL, f128, round));         \
61   printf(#insn " %Lf\n", L2F(insn, 0x7fffffffUL, f128, round));         \
62   printf(#insn " %Lf\n", L2F(insn, 0x100000000UL, f128, round));        \
63   printf(#insn " %Lf\n", L2F(insn, 0xffffffffffffffffUL, f128, round)); \
64   printf(#insn " %Lf\n", L2F(insn, 0x8000000000000000UL, f128, round)); \
65   printf(#insn " %Lf\n", L2F(insn, 0x7fffffffffffffffUL, f128, round)); \
66})
67
68#define DO_INSN_F2L(insn, round, type)                                   \
69({                                                                       \
70   int cc;                                                               \
71   printf(#insn " %lu ", F2L(insn, -1.1, type, round, cc));              \
72   printf("cc=%d\n", cc);                                                \
73   printf(#insn " %lu ", F2L(insn, 0, type, round, cc));                 \
74   printf("cc=%d\n", cc);                                                \
75   printf(#insn " %lu ", F2L(insn, 1, type, round, cc));                 \
76   printf("cc=%d\n", cc);                                                \
77   printf(#insn " %lu ", F2L(insn, 1.4, type, round, cc));               \
78   printf("cc=%d\n", cc);                                                \
79   printf(#insn " %lu ", F2L(insn, 1.5, type, round, cc));               \
80   printf("cc=%d\n", cc);                                                \
81   printf(#insn " %lu ", F2L(insn, 1.6, type, round, cc));               \
82   printf("cc=%d\n", cc);                                                \
83   printf(#insn " %lu ", F2L(insn, 1.6E+4, type, round, cc));            \
84   printf("cc=%d\n", cc);                                                \
85   printf(#insn " %lu ", F2L(insn, 1.6E+8, type, round, cc));            \
86   printf("cc=%d\n", cc);                                                \
87   printf(#insn " %lu ", F2L(insn, 1.6E+12, type, round, cc));           \
88   printf("cc=%d\n", cc);                                                \
89   printf(#insn " %lu ", F2L(insn, 1.6E+20, type, round, cc));           \
90   printf("cc=%d\n", cc);                                                \
91   printf(#insn " %lu ", F2L(insn, 1.6E+200, type, round, cc));          \
92   printf("cc=%d\n", cc);                                                \
93   printf(#insn " %lu ", F2L(insn, 1.6E+2000L, type, round, cc));        \
94   printf("cc=%d\n", cc);                                                \
95   printf(#insn " %lu ", F2L(insn, 1.6E-4, type, round, cc));            \
96   printf("cc=%d\n", cc);                                                \
97   printf(#insn " %lu ", F2L(insn, FLT_MIN, type, round, cc));           \
98   printf("cc=%d\n", cc);                                                \
99   printf(#insn " %lu ", F2L(insn, FLT_MAX, type, round, cc));           \
100   printf("cc=%d\n", cc);                                                \
101   printf(#insn " %lu ", F2L(insn, DBL_MIN, type, round, cc));           \
102   printf("cc=%d\n", cc);                                                \
103   printf(#insn " %lu ", F2L(insn, DBL_MAX, type, round, cc));           \
104   printf("cc=%d\n", cc);                                                \
105   printf(#insn " %lu ", F2L(insn, LDBL_MIN, type, round, cc));          \
106   printf("cc=%d\n", cc);                                                \
107   printf(#insn " %lu ", F2L(insn, LDBL_MAX, type, round, cc));          \
108   printf("cc=%d\n", cc);                                                \
109})
110
111#define DO_L2F(round)                                                    \
112({                                                                       \
113   DO_INSN_L2F32(CELFBR, round);                                         \
114   DO_INSN_L2F32(CELGBR, round);                                         \
115   DO_INSN_L2F64(CDLFBR, round);                                         \
116   DO_INSN_L2F64(CDLGBR, round);                                         \
117   DO_INSN_L2F128(CXLFBR, round);                                        \
118   DO_INSN_L2F128(CXLGBR, round);                                        \
119})
120
121#define DO_F2L(round)                                                    \
122({                                                                       \
123   DO_INSN_F2L(CLFEBR, round, float);                                    \
124   DO_INSN_F2L(CLGEBR, round, float);                                    \
125   DO_INSN_F2L(CLFDBR, round, double);                                   \
126   DO_INSN_F2L(CLGDBR, round, double);                                   \
127   DO_INSN_F2L(CLFXBR, round, long double);                              \
128   DO_INSN_F2L(CLGXBR, round, long double);                              \
129})
130
131
132int main()
133{
134   DO_L2F(4);
135   DO_F2L(4);
136
137   DO_L2F(5);
138   DO_F2L(5);
139
140   DO_L2F(6);
141   DO_F2L(6);
142
143   DO_L2F(7);
144   DO_F2L(7);
145
146   return 0;
147}
148