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 } 79