1#include <assert.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <stdint.h>
5#include <inttypes.h>
6#include "opcodes.h"
7#include "rounding.h"
8
9/* Test "fixbr"  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.
13*/
14
15const char *
16rtext(unsigned m3_round)
17{
18   switch (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]";
26   }
27   assert(0);
28}
29
30#define round_to_int(value,round)                             \
31do {                                                          \
32   long double src = value;                                   \
33   long double dst;                                           \
34                                                              \
35   __asm__ volatile ("fixbr %[dst]," #round ",%[src]\n\t"     \
36                     : [dst] "=f"(dst)                        \
37                     : [src] "f"(src));                       \
38                                                              \
39   printf("fixbr %.5Lf\t-> %Lg  %s\n",                        \
40          src, dst, rtext(round));                            \
41} while (0)
42
43#define fixbr(value,round) round_to_int(value,round)
44
45void
46set_rounding_mode(unsigned mode)
47{
48   register unsigned r asm("1") = mode;
49   __asm__ volatile ( SFPC(1) : : "d"(r) );
50}
51
52
53int main(void)
54{
55   int j;
56   static const long double dval[] = {
57      1.25, 1.5, 2.5, 1.75, -1.25, -1.5, -2.5, -1.75, 0.0,
58   };
59
60   assert(sizeof(long double) == 16);
61
62   /* f128 -> f128, round to int */
63   for (j = 0; j < sizeof dval / sizeof dval[0]; ++j) {
64      set_rounding_mode(FPC_BFP_ROUND_ZERO);
65      fixbr(dval[j], M3_BFP_ROUND_NEAREST_EVEN);
66      set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN);
67      fixbr(dval[j], M3_BFP_ROUND_ZERO);
68      fixbr(dval[j], M3_BFP_ROUND_POSINF);
69      fixbr(dval[j], M3_BFP_ROUND_NEGINF);
70   }
71
72   return 0;
73}
74