Lines 30-38
Link Here
|
30 |
* Adapted from https://github.com/freebsd/freebsd-src/search?q=__double_t |
30 |
* Adapted from https://github.com/freebsd/freebsd-src/search?q=__double_t |
31 |
*/ |
31 |
*/ |
32 |
|
32 |
|
|
|
33 |
#ifdef __LP64__ |
33 |
typedef double __double_t; |
34 |
typedef double __double_t; |
|
|
35 |
#else |
36 |
typedef long double __double_t; |
37 |
#endif |
34 |
typedef __double_t double_t; |
38 |
typedef __double_t double_t; |
35 |
|
39 |
typedef float __float_t; |
36 |
/* |
40 |
/* |
37 |
* The original fdlibm code used statements like: |
41 |
* The original fdlibm code used statements like: |
38 |
* n0 = ((*(int*)&one)>>29)^1; * index of high word * |
42 |
* n0 = ((*(int*)&one)>>29)^1; * index of high word * |
Lines 630-635
Link Here
|
630 |
return ((double)(x + 0x1.8p52) - 0x1.8p52); |
634 |
return ((double)(x + 0x1.8p52) - 0x1.8p52); |
631 |
} |
635 |
} |
632 |
|
636 |
|
|
|
637 |
static inline float |
638 |
rnintf(__float_t x) |
639 |
{ |
640 |
/* |
641 |
* As for rnint(), except we could just call that to handle the |
642 |
* extra precision case, usually without losing efficiency. |
643 |
*/ |
644 |
return ((float)(x + 0x1.8p23F) - 0x1.8p23F); |
645 |
} |
646 |
|
647 |
#ifdef LDBL_MANT_DIG |
648 |
/* |
649 |
* The complications for extra precision are smaller for rnintl() since it |
650 |
* can safely assume that the rounding precision has been increased from |
651 |
* its default to FP_PE on x86. We don't exploit that here to get small |
652 |
* optimizations from limiting the rangle to double. We just need it for |
653 |
* the magic number to work with long doubles. ld128 callers should use |
654 |
* rnint() instead of this if possible. ld80 callers should prefer |
655 |
* rnintl() since for amd64 this avoids swapping the register set, while |
656 |
* for i386 it makes no difference (assuming FP_PE), and for other arches |
657 |
* it makes little difference. |
658 |
*/ |
659 |
static inline long double |
660 |
rnintl(long double x) |
661 |
{ |
662 |
#if (LDBL_MANT_DIG == 64) |
663 |
return (x + __CONCAT(0x1.8p, 64) / 2 - |
664 |
__CONCAT(0x1.8p, 64) / 2); |
665 |
#else |
666 |
return (x + __CONCAT(0x1.8p, LDBL_MANT_DIG) / 2 - |
667 |
__CONCAT(0x1.8p, LDBL_MANT_DIG) / 2); |
668 |
#endif |
669 |
} |
670 |
#endif /* LDBL_MANT_DIG */ |
671 |
|
633 |
/* |
672 |
/* |
634 |
* irint() and i64rint() give the same result as casting to their integer |
673 |
* irint() and i64rint() give the same result as casting to their integer |
635 |
* return type provided their arg is a floating point integer. They can |
674 |
* return type provided their arg is a floating point integer. They can |
Lines 646-651
Link Here
|
646 |
#define irint(x) ((int)(x)) |
685 |
#define irint(x) ((int)(x)) |
647 |
#endif |
686 |
#endif |
648 |
|
687 |
|
|
|
688 |
#define i64rint(x) ((int64_t)(x)) /* only needed for ld128 so not opt. */ |
689 |
|
690 |
#if defined(__i386__) && defined(__GNUCLIKE_ASM) |
691 |
static __inline int |
692 |
irintf(float x) |
693 |
{ |
694 |
int n; |
695 |
|
696 |
__asm("fistl %0" : "=m" (n) : "t" (x)); |
697 |
return (n); |
698 |
} |
699 |
|
700 |
static __inline int |
701 |
irintd(double x) |
702 |
{ |
703 |
int n; |
704 |
|
705 |
__asm("fistl %0" : "=m" (n) : "t" (x)); |
706 |
return (n); |
707 |
} |
708 |
#endif |
709 |
|
710 |
#if (defined(__amd64__) || defined(__i386__)) && defined(__GNUCLIKE_ASM) |
711 |
static __inline int |
712 |
irintl(long double x) |
713 |
{ |
714 |
int n; |
715 |
|
716 |
__asm("fistl %0" : "=m" (n) : "t" (x)); |
717 |
return (n); |
718 |
} |
719 |
#endif |
720 |
|
649 |
#ifdef DEBUG |
721 |
#ifdef DEBUG |
650 |
#if defined(__amd64__) || defined(__i386__) |
722 |
#if defined(__amd64__) || defined(__i386__) |
651 |
#define breakpoint() asm("int $3") |
723 |
#define breakpoint() asm("int $3") |