9 /* Test "convert to fixed" with rounding mode given in insn (m3 field)
10 Covers all generally available rounding modes that can be mapped to
11 IRRoundingMode. As a consequence m3=1 which is "round to nearest with
12 ties away from 0" is not tested here.
16 rtext(unsigned m3_round
)
19 case 0: return "[-> per fpc]";
20 case 1: return "[-> nearest away]";
21 case 3: return "[-> prepare short]"; // floating point extension fac needed
22 case 4: return "[-> nearest even]";
23 case 5: return "[-> 0]";
24 case 6: return "[-> +inf]";
25 case 7: return "[-> -inf]";
30 #define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \
32 src_type src = value; \
36 __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \
39 : [dst] "=d"(dst), [cc] "=d"(cc) \
43 printf("%s %f\t-> %"dst_fmt"\tcc = %u %s\n", \
44 opcode, src, dst, cc, rtext(round)); \
47 #define round_to_int(opcode,type,round,value) \
52 __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \
56 printf("%s %.5f\t-> %g %s\n", \
57 opcode, src, dst, rtext(round)); \
61 #define cfebr(value, round) \
62 convert_to_int("cfebr",float,int32_t,PRId32,round,value)
63 #define cfdbr(value, round) \
64 convert_to_int("cfdbr",double,int32_t,PRId32,round,value)
65 #define cgebr(value, round) \
66 convert_to_int("cgebr",float,int64_t,PRId64,round,value)
67 #define cgdbr(value, round) \
68 convert_to_int("cgdbr",double,int64_t,PRId64,round,value)
70 #define fiebr(value, round) \
71 round_to_int("fiebr",float,round,value)
72 #define fidbr(value, round) \
73 round_to_int("fidbr",double,round,value)
76 set_rounding_mode(unsigned mode
)
78 register unsigned r
asm("1") = mode
;
79 __asm__
volatile ( SFPC(1) : : "d"(r
) );
86 static const float fval
[] = {
87 1.25f
, 1.5f
, 2.5f
, 1.75f
, -1.25f
, -1.5f
, -2.5f
, -1.75f
, 0.0f
,
89 static const double dval
[] = {
90 1.25, 1.5, 2.5, 1.75, -1.25, -1.5, -2.5, -1.75, 0.0,
93 /* Note when testing M3_NEAR need to set the FPC rounding mode
94 to something else. FPC rounding mode is NEAR by default.
95 Setting the FPC rounding mode to != NEAR is the only way to make
96 sure the M3 field is not ignored. */
99 for (j
= 0; j
< sizeof fval
/ sizeof fval
[0]; ++j
) {
100 set_rounding_mode(FPC_BFP_ROUND_ZERO
);
101 cfebr(fval
[j
], M3_BFP_ROUND_NEAREST_EVEN
);
102 set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN
);
103 cfebr(fval
[j
], M3_BFP_ROUND_ZERO
);
104 cfebr(fval
[j
], M3_BFP_ROUND_POSINF
);
105 cfebr(fval
[j
], M3_BFP_ROUND_NEGINF
);
109 for (j
= 0; j
< sizeof fval
/ sizeof fval
[0]; ++j
) {
110 set_rounding_mode(FPC_BFP_ROUND_ZERO
);
111 cgebr(fval
[j
], M3_BFP_ROUND_NEAREST_EVEN
);
112 set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN
);
113 cgebr(fval
[j
], M3_BFP_ROUND_ZERO
);
114 cgebr(fval
[j
], M3_BFP_ROUND_POSINF
);
115 cgebr(fval
[j
], M3_BFP_ROUND_NEGINF
);
119 for (j
= 0; j
< sizeof dval
/ sizeof dval
[0]; ++j
) {
120 set_rounding_mode(FPC_BFP_ROUND_ZERO
);
121 cfdbr(dval
[j
], M3_BFP_ROUND_NEAREST_EVEN
);
122 set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN
);
123 cfdbr(dval
[j
], M3_BFP_ROUND_ZERO
);
124 cfdbr(dval
[j
], M3_BFP_ROUND_POSINF
);
125 cfdbr(dval
[j
], M3_BFP_ROUND_NEGINF
);
129 for (j
= 0; j
< sizeof dval
/ sizeof dval
[0]; ++j
) {
130 set_rounding_mode(FPC_BFP_ROUND_ZERO
);
131 cgdbr(dval
[j
], M3_BFP_ROUND_NEAREST_EVEN
);
132 set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN
);
133 cgdbr(dval
[j
], M3_BFP_ROUND_ZERO
);
134 cgdbr(dval
[j
], M3_BFP_ROUND_POSINF
);
135 cgdbr(dval
[j
], M3_BFP_ROUND_NEGINF
);
138 /* f32 -> f32, round to int */
139 for (j
= 0; j
< sizeof dval
/ sizeof dval
[0]; ++j
) {
140 set_rounding_mode(FPC_BFP_ROUND_ZERO
);
141 fiebr(dval
[j
], M3_BFP_ROUND_NEAREST_EVEN
);
142 set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN
);
143 fiebr(dval
[j
], M3_BFP_ROUND_ZERO
);
144 fiebr(dval
[j
], M3_BFP_ROUND_POSINF
);
145 fiebr(dval
[j
], M3_BFP_ROUND_NEGINF
);
148 /* f64 -> f64, round to int */
149 for (j
= 0; j
< sizeof dval
/ sizeof dval
[0]; ++j
) {
150 set_rounding_mode(FPC_BFP_ROUND_ZERO
);
151 fidbr(dval
[j
], M3_BFP_ROUND_NEAREST_EVEN
);
152 set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN
);
153 fidbr(dval
[j
], M3_BFP_ROUND_ZERO
);
154 fidbr(dval
[j
], M3_BFP_ROUND_POSINF
);
155 fidbr(dval
[j
], M3_BFP_ROUND_NEGINF
);