• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
10 const char *
rtext(unsigned round)11 rtext(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) \
27 do { \
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 
main(void)47 int 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