rounding-1.c revision 436e89c602e787e7a27dd6624b09beed41a0da8a
1#include <stdlib.h>
2#include <assert.h>
3#include <stdio.h>
4#include <stdint.h>
5#include <inttypes.h>
6
7/* This testcase is to illustrate that for convert to fixed the condition
8   code depends on the rounding mode. */
9
10const char *
11rtext(unsigned round)
12{
13   switch (round) {
14   case 0: return "[fpc]";
15   case 1: return "[->near/away]";
16      /* 2 is invalid */
17   case 3: return "[prep short]";
18   case 4: return "[->near/even]";
19   case 5: return "[->0]";
20   case 6: return "[->+inf]";
21   case 7: return "[->-inf]";
22   }
23   assert(0);
24}
25
26#define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \
27do { \
28   src_type src = value; \
29   dst_type dst;         \
30   unsigned cc;          \
31                         \
32   __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t"     \
33                     "ipm %[cc]\n\t"                  \
34                     "srl %[cc],28\n\t"               \
35                     : [dst] "=d"(dst), [cc] "=d"(cc) \
36                     : [src] "f"(src)                 \
37                     : "cc");                         \
38                                                      \
39   printf("%s %-20s %f\t-> %"dst_fmt"\tcc = %u\n",    \
40          opcode, rtext(round), src, dst, cc);        \
41} while (0)
42
43
44#define cfdbr(round,value) \
45        convert_to_int("cfdbr",double,int32_t,PRId32,round,value)
46
47int main(void)
48{
49   double dval;
50
51   dval = -2147483648.5;  // a < MN
52
53   // f64 -> i32
54
55   cfdbr(4, dval);  // round to nearest with ties to even
56   cfdbr(5, dval);  // round to zero
57   cfdbr(6, dval);  // round to +inf
58
59   /* The next invocation needs to give cc=3. It used to give cc=1 when
60      we were considering the to-be-converted value ONLY */
61   cfdbr(7, dval);  // round to -inf
62
63   return 0;
64}
65