1*7012b691SRichard Henderson #include <stdio.h>
2*7012b691SRichard Henderson
3*7012b691SRichard Henderson #define FPCR_SUM (1UL << 63)
4*7012b691SRichard Henderson #define FPCR_INED (1UL << 62)
5*7012b691SRichard Henderson #define FPCR_UNFD (1UL << 61)
6*7012b691SRichard Henderson #define FPCR_UNDZ (1UL << 60)
7*7012b691SRichard Henderson #define FPCR_DYN_SHIFT 58
8*7012b691SRichard Henderson #define FPCR_DYN_CHOPPED (0UL << FPCR_DYN_SHIFT)
9*7012b691SRichard Henderson #define FPCR_DYN_MINUS (1UL << FPCR_DYN_SHIFT)
10*7012b691SRichard Henderson #define FPCR_DYN_NORMAL (2UL << FPCR_DYN_SHIFT)
11*7012b691SRichard Henderson #define FPCR_DYN_PLUS (3UL << FPCR_DYN_SHIFT)
12*7012b691SRichard Henderson #define FPCR_DYN_MASK (3UL << FPCR_DYN_SHIFT)
13*7012b691SRichard Henderson #define FPCR_IOV (1UL << 57)
14*7012b691SRichard Henderson #define FPCR_INE (1UL << 56)
15*7012b691SRichard Henderson #define FPCR_UNF (1UL << 55)
16*7012b691SRichard Henderson #define FPCR_OVF (1UL << 54)
17*7012b691SRichard Henderson #define FPCR_DZE (1UL << 53)
18*7012b691SRichard Henderson #define FPCR_INV (1UL << 52)
19*7012b691SRichard Henderson #define FPCR_OVFD (1UL << 51)
20*7012b691SRichard Henderson #define FPCR_DZED (1UL << 50)
21*7012b691SRichard Henderson #define FPCR_INVD (1UL << 49)
22*7012b691SRichard Henderson #define FPCR_DNZ (1UL << 48)
23*7012b691SRichard Henderson #define FPCR_DNOD (1UL << 47)
24*7012b691SRichard Henderson #define FPCR_STATUS_MASK (FPCR_IOV | FPCR_INE | FPCR_UNF \
25*7012b691SRichard Henderson | FPCR_OVF | FPCR_DZE | FPCR_INV)
26*7012b691SRichard Henderson
test_cvttq(long * ret_e,double d)27*7012b691SRichard Henderson static long test_cvttq(long *ret_e, double d)
28*7012b691SRichard Henderson {
29*7012b691SRichard Henderson unsigned long reset = (FPCR_INED | FPCR_UNFD | FPCR_OVFD | FPCR_DZED |
30*7012b691SRichard Henderson FPCR_INVD | FPCR_DYN_NORMAL);
31*7012b691SRichard Henderson long r, e;
32*7012b691SRichard Henderson
33*7012b691SRichard Henderson asm("excb\n\t"
34*7012b691SRichard Henderson "mt_fpcr %3\n\t"
35*7012b691SRichard Henderson "excb\n\t"
36*7012b691SRichard Henderson "cvttq/svic %2, %0\n\t"
37*7012b691SRichard Henderson "excb\n\t"
38*7012b691SRichard Henderson "mf_fpcr %1\n\t"
39*7012b691SRichard Henderson "excb\n\t"
40*7012b691SRichard Henderson : "=f"(r), "=f"(e)
41*7012b691SRichard Henderson : "f"(d), "f"(reset));
42*7012b691SRichard Henderson
43*7012b691SRichard Henderson *ret_e = e & FPCR_STATUS_MASK;
44*7012b691SRichard Henderson return r;
45*7012b691SRichard Henderson }
46*7012b691SRichard Henderson
main(void)47*7012b691SRichard Henderson int main (void)
48*7012b691SRichard Henderson {
49*7012b691SRichard Henderson static const struct {
50*7012b691SRichard Henderson double d;
51*7012b691SRichard Henderson long r;
52*7012b691SRichard Henderson long e;
53*7012b691SRichard Henderson } T[] = {
54*7012b691SRichard Henderson { 1.0, 1, 0 },
55*7012b691SRichard Henderson { -1.0, -1, 0 },
56*7012b691SRichard Henderson { 1.5, 1, FPCR_INE },
57*7012b691SRichard Henderson { 0x1.0p32, 0x0000000100000000ul, 0 },
58*7012b691SRichard Henderson { -0x1.0p63, 0x8000000000000000ul, 0 },
59*7012b691SRichard Henderson { 0x1.0p63, 0x8000000000000000ul, FPCR_IOV | FPCR_INE },
60*7012b691SRichard Henderson { 0x1.0p64, 0x0000000000000000ul, FPCR_IOV | FPCR_INE },
61*7012b691SRichard Henderson { 0x1.cccp64, 0xccc0000000000000ul, FPCR_IOV | FPCR_INE },
62*7012b691SRichard Henderson { __builtin_inf(), 0, FPCR_INV },
63*7012b691SRichard Henderson { __builtin_nan(""), 0, FPCR_INV },
64*7012b691SRichard Henderson };
65*7012b691SRichard Henderson
66*7012b691SRichard Henderson int i, err = 0;
67*7012b691SRichard Henderson
68*7012b691SRichard Henderson for (i = 0; i < sizeof(T)/sizeof(T[0]); i++) {
69*7012b691SRichard Henderson long e, r = test_cvttq(&e, T[i].d);
70*7012b691SRichard Henderson
71*7012b691SRichard Henderson if (r != T[i].r || e != T[i].e) {
72*7012b691SRichard Henderson printf("Fail %a: expect (%016lx : %04lx) got (%016lx : %04lx)\n",
73*7012b691SRichard Henderson T[i].d, T[i].r, T[i].e >> 48, r, e >> 48);
74*7012b691SRichard Henderson err = 1;
75*7012b691SRichard Henderson }
76*7012b691SRichard Henderson }
77*7012b691SRichard Henderson return err;
78*7012b691SRichard Henderson }
79