1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <float.h>
2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdio.h>
3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdint.h>
4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <inttypes.h>
5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <limits.h>
6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* The following opcodes are tested:
8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Convert to fixed:    cfebr, cgebr, cfdbr, cgdbr
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Convert from fixed:  cefbr, cdfbr, cegbr, cdgbr
11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   We do not test rounding here. Just making sure the insn selector
13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   picks the correct insn.
14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov*/
15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define I2F(insn, initial, target_type)                         \
17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdo {                                                            \
18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   int64_t source = initial;                                    \
19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   target_type target;                                          \
20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   asm volatile(insn " %0,%1\n\t" :"=f" (target) :"d"(source)); \
21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf(insn " %"PRId64" -> %f\n", source, target);           \
22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} while (0)
23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define DO_INSN_I32_TO_F(insn, target_type)        \
25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdo {                                               \
26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n----- int32_t -> " #target_type "\n");\
27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn,   0, target_type);                    \
28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn,   1, target_type);                    \
29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn,  -1, target_type);                    \
30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn,  42, target_type);                    \
31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, SHRT_MAX, target_type);               \
32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, SHRT_MIN, target_type);               \
33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, INT_MAX, target_type);                \
34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, INT_MIN, target_type);                \
35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} while (0)
36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define DO_INSN_I64_TO_F(insn, target_type)        \
38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdo {                                               \
39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n----- int64_t -> " #target_type "\n");\
40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn,   0, target_type);                    \
41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn,   1, target_type);                    \
42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn,  -1, target_type);                    \
43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn,  42, target_type);                    \
44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, SHRT_MAX, target_type);               \
45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, SHRT_MIN, target_type);               \
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, INT_MAX, target_type);                \
47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, INT_MIN, target_type);                \
48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, LONG_MAX, target_type);               \
49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   I2F(insn, LONG_MIN, target_type);               \
50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} while (0)
51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define DO_I2F()                        \
53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdo {                                    \
54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_INSN_I32_TO_F("cefbr", float);    \
55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_INSN_I32_TO_F("cdfbr", double);   \
56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_INSN_I64_TO_F("cegbr", float);    \
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_INSN_I64_TO_F("cdgbr", double);   \
58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} while (0)
59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define F2I(insn, initial, source_type, target_type)               \
62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdo {                                                               \
63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   int cc;                                                         \
64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   source_type source = initial;                                   \
65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   target_type target = 0;                                         \
66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   asm volatile(insn " %0,0,%2\n\t"                                \
67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                "ipm %1\n\t"                                       \
68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                "srl %1,28\n\t"                                    \
69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 		: "=d" (target), "=d" (cc) : "f"(source) : "cc");  \
70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf(insn " %f -> %ld   cc = %d\n", source, (long)target, cc); \
71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} while (0)
72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define DO_INSN_F32_TO_I(insn, type)          \
74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdo {                                          \
75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n----- float -> " #type "\n");    \
76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, -1.0f, float, type);             \
77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn,  0.0f, float, type);             \
78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn,  1.0f, float, type);             \
79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.4f, float, type);              \
80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.5f, float, type);              \
81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.6f, float, type);              \
82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.6E+4f, float, type);           \
83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.6E+8f, float, type);           \
84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.6E-4f, float, type);           \
85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, FLT_MAX, float, type);           \
86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} while (0)
87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define DO_INSN_F64_TO_I(insn, type)          \
89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdo {                                          \
90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   printf("\n----- double -> " #type "\n");   \
91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, -1.0, double, type);             \
92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn,  0.0, double, type);             \
93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn,  1.0, double, type);             \
94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.4, double, type);              \
95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.5, double, type);              \
96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.6, double, type);              \
97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.6E+4, double, type);           \
98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.6E+8, double, type);           \
99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, 1.6E-4, double, type);           \
100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, FLT_MAX, double, type);          \
101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   F2I(insn, DBL_MAX, double, type);          \
102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} while (0)
103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define DO_F2I()                        \
105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdo {                                    \
106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_INSN_F32_TO_I("cfebr", int32_t);  \
107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_INSN_F32_TO_I("cgebr", int64_t);  \
108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_INSN_F64_TO_I("cfdbr", int32_t);  \
109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_INSN_F64_TO_I("cgdbr", int64_t);  \
110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} while (0)
111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint main()
114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_I2F();
116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DO_F2I();
117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return 0;
119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
120