• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <float.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <inttypes.h>
5 #include <limits.h>
6 
7 /* The following opcodes are tested:
8 
9    Convert to fixed:    cfebr, cgebr, cfdbr, cgdbr
10    Convert from fixed:  cefbr, cdfbr, cegbr, cdgbr
11 
12    We do not test rounding here. Just making sure the insn selector
13    picks the correct insn.
14 */
15 
16 #define I2F(insn, initial, target_type)                         \
17 do {                                                            \
18    int64_t source = initial;                                    \
19    target_type target;                                          \
20    asm volatile(insn " %0,%1\n\t" :"=f" (target) :"d"(source)); \
21    printf(insn " %"PRId64" -> %f\n", source, target);           \
22 } while (0)
23 
24 #define DO_INSN_I32_TO_F(insn, target_type)        \
25 do {                                               \
26    printf("\n----- int32_t -> " #target_type "\n");\
27    I2F(insn,   0, target_type);                    \
28    I2F(insn,   1, target_type);                    \
29    I2F(insn,  -1, target_type);                    \
30    I2F(insn,  42, target_type);                    \
31    I2F(insn, SHRT_MAX, target_type);               \
32    I2F(insn, SHRT_MIN, target_type);               \
33    I2F(insn, INT_MAX, target_type);                \
34    I2F(insn, INT_MIN, target_type);                \
35 } while (0)
36 
37 #define DO_INSN_I64_TO_F(insn, target_type)        \
38 do {                                               \
39    printf("\n----- int64_t -> " #target_type "\n");\
40    I2F(insn,   0, target_type);                    \
41    I2F(insn,   1, target_type);                    \
42    I2F(insn,  -1, target_type);                    \
43    I2F(insn,  42, target_type);                    \
44    I2F(insn, SHRT_MAX, target_type);               \
45    I2F(insn, SHRT_MIN, target_type);               \
46    I2F(insn, INT_MAX, target_type);                \
47    I2F(insn, INT_MIN, target_type);                \
48    I2F(insn, LONG_MAX, target_type);               \
49    I2F(insn, LONG_MIN, target_type);               \
50 } while (0)
51 
52 #define DO_I2F()                        \
53 do {                                    \
54    DO_INSN_I32_TO_F("cefbr", float);    \
55    DO_INSN_I32_TO_F("cdfbr", double);   \
56    DO_INSN_I64_TO_F("cegbr", float);    \
57    DO_INSN_I64_TO_F("cdgbr", double);   \
58 } while (0)
59 
60 
61 #define F2I(insn, initial, source_type, target_type)               \
62 do {                                                               \
63    int cc;                                                         \
64    source_type source = initial;                                   \
65    target_type target = 0;                                         \
66    asm volatile(insn " %0,0,%2\n\t"                                \
67                 "ipm %1\n\t"                                       \
68                 "srl %1,28\n\t"                                    \
69  		: "=d" (target), "=d" (cc) : "f"(source) : "cc");  \
70    printf(insn " %f -> %ld   cc = %d\n", source, (long)target, cc); \
71 } while (0)
72 
73 #define DO_INSN_F32_TO_I(insn, type)          \
74 do {                                          \
75    printf("\n----- float -> " #type "\n");    \
76    F2I(insn, -1.0f, float, type);             \
77    F2I(insn,  0.0f, float, type);             \
78    F2I(insn,  1.0f, float, type);             \
79    F2I(insn, 1.4f, float, type);              \
80    F2I(insn, 1.5f, float, type);              \
81    F2I(insn, 1.6f, float, type);              \
82    F2I(insn, 1.6E+4f, float, type);           \
83    F2I(insn, 1.6E+8f, float, type);           \
84    F2I(insn, 1.6E-4f, float, type);           \
85    F2I(insn, FLT_MAX, float, type);           \
86 } while (0)
87 
88 #define DO_INSN_F64_TO_I(insn, type)          \
89 do {                                          \
90    printf("\n----- double -> " #type "\n");   \
91    F2I(insn, -1.0, double, type);             \
92    F2I(insn,  0.0, double, type);             \
93    F2I(insn,  1.0, double, type);             \
94    F2I(insn, 1.4, double, type);              \
95    F2I(insn, 1.5, double, type);              \
96    F2I(insn, 1.6, double, type);              \
97    F2I(insn, 1.6E+4, double, type);           \
98    F2I(insn, 1.6E+8, double, type);           \
99    F2I(insn, 1.6E-4, double, type);           \
100    F2I(insn, FLT_MAX, double, type);          \
101    F2I(insn, DBL_MAX, double, type);          \
102 } while (0)
103 
104 #define DO_F2I()                        \
105 do {                                    \
106    DO_INSN_F32_TO_I("cfebr", int32_t);  \
107    DO_INSN_F32_TO_I("cgebr", int64_t);  \
108    DO_INSN_F64_TO_I("cfdbr", int32_t);  \
109    DO_INSN_F64_TO_I("cgdbr", int64_t);  \
110 } while (0)
111 
112 
main()113 int main()
114 {
115    DO_I2F();
116    DO_F2I();
117 
118    return 0;
119 }
120