8 /* Test "convert to fixed" with "per fpc" rounding.
9 Covers all generally available rounding modes.
13 set_rounding_mode(unsigned mode
)
15 register unsigned r
asm("1") = mode
;
16 __asm__
volatile ( SFPC(1) : : "d"(r
) );
20 get_rounding_mode(void)
24 __asm__
volatile ("stfpc %0" : "=Q"(fpc
));
31 rtext(unsigned fpc_round
)
34 case 0: return "[-> near]";
35 case 1: return "[-> zero]";
36 case 2: return "[-> +inf]";
37 case 3: return "[-> -inf]";
42 #define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \
44 src_type src = value; \
48 __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \
51 : [dst] "=d"(dst), [cc] "=d"(cc) \
55 printf("%s %f\t-> %"dst_fmt"\tcc = %u\n", \
56 opcode, src, dst, cc); \
60 #define cfebr(value) \
61 convert_to_int("cfebr",float,int32_t,PRId32,0,value)
62 #define cfdbr(value) \
63 convert_to_int("cfdbr",double,int32_t,PRId32,0,value)
64 #define cgebr(value) \
65 convert_to_int("cgebr",float,int64_t,PRId64,0,value)
66 #define cgdbr(value) \
67 convert_to_int("cgdbr",double,int64_t,PRId64,0,value)
72 static const unsigned rmodes
[] = { 0, 1, 2, 3 };
73 static const float fval
[] = {
74 1.25f
, 1.5f
, 2.5f
, 1.75f
, -1.25f
, -1.5f
, -2.5f
, -1.75f
, 0.0f
,
76 static const double dval
[] = {
77 1.25, 1.5, 2.5, 1.75, -1.25, -1.5, -2.5, -1.75, 0.0,
81 for (i
= 0; i
< sizeof rmodes
/ sizeof rmodes
[0]; ++i
) {
82 printf("setting rounding mode to %s\n", rtext(rmodes
[i
]));
83 set_rounding_mode(rmodes
[i
]);
84 assert(get_rounding_mode() == rmodes
[i
]);
87 for (j
= 0; j
< sizeof fval
/ sizeof fval
[0]; ++j
) {
89 assert(get_rounding_mode() == rmodes
[i
]);
93 for (j
= 0; j
< sizeof fval
/ sizeof fval
[0]; ++j
) {
95 assert(get_rounding_mode() == rmodes
[i
]);
99 for (j
= 0; j
< sizeof dval
/ sizeof dval
[0]; ++j
) {
101 assert(get_rounding_mode() == rmodes
[i
]);
105 for (j
= 0; j
< sizeof dval
/ sizeof dval
[0]; ++j
) {
107 assert(get_rounding_mode() == rmodes
[i
]);