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