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
15 const char *
rtext(unsigned m3_round)16 rtext(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) \
31 do { \
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
45 void
set_rounding_mode(unsigned mode)46 set_rounding_mode(unsigned mode)
47 {
48 register unsigned r asm("1") = mode;
49 __asm__ volatile ( SFPC(1) : : "d"(r) );
50 }
51
52
main(void)53 int 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