Pull in r231965 from upstream compiler-rt trunk (by Jörg Sonnenberger):
Refactor float to integer conversion to share the same code. 80bit Intel/PPC long double is excluded due to lacking support for the abstraction. Consistently provide saturation logic. Extend to long double on 128bit IEEE extended platforms. Initial patch with test cases from GuanHong Liu. Reviewed by Steve Canon. Differential Revision: http://reviews.llvm.org/D2804 Pull in r232107 from upstream compiler-rt trunk (by Ed Maste): Use signed int implementation for __fixint Requested by: emaste
This commit is contained in:
parent
cee9be4971
commit
25e141edd2
@ -6,40 +6,17 @@
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixdfdi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: convert a to a signed long long, rounding toward zero. */
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* su_int is a 32 bit integral type
|
||||
* value in double is representable in di_int (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
ARM_EABI_FNALIAS(d2lz, fixdfdi)
|
||||
|
||||
typedef di_int fixint_t;
|
||||
typedef du_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixdfdi(double a)
|
||||
{
|
||||
double_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
|
||||
if (e < 0)
|
||||
return 0;
|
||||
di_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31;
|
||||
dwords r;
|
||||
r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
|
||||
r.s.low = fb.u.s.low;
|
||||
if (e > 52)
|
||||
r.all <<= (e - 52);
|
||||
else
|
||||
r.all >>= (52 - e);
|
||||
return (r.all ^ s) - s;
|
||||
}
|
||||
__fixdfdi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
@ -1,50 +1,22 @@
|
||||
//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements double-precision to integer conversion for the
|
||||
// compiler-rt library. No range checking is performed; the behavior of this
|
||||
// conversion is undefined for out of range values in the C standard.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/* ===-- fixdfsi.c - Implement __fixdfsi -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#include "int_lib.h"
|
||||
typedef si_int fixint_t;
|
||||
typedef su_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
ARM_EABI_FNALIAS(d2iz, fixdfsi)
|
||||
|
||||
COMPILER_RT_ABI int
|
||||
COMPILER_RT_ABI si_int
|
||||
__fixdfsi(fp_t a) {
|
||||
|
||||
// Break a into sign, exponent, significand
|
||||
const rep_t aRep = toRep(a);
|
||||
const rep_t aAbs = aRep & absMask;
|
||||
const int sign = aRep & signBit ? -1 : 1;
|
||||
const int exponent = (aAbs >> significandBits) - exponentBias;
|
||||
const rep_t significand = (aAbs & significandMask) | implicitBit;
|
||||
|
||||
// If 0 < exponent < significandBits, right shift to get the result.
|
||||
if ((unsigned int)exponent < significandBits) {
|
||||
return sign * (significand >> (significandBits - exponent));
|
||||
}
|
||||
|
||||
// If exponent is negative, the result is zero.
|
||||
else if (exponent < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If significandBits < exponent, left shift to get the result. This shift
|
||||
// may end up being larger than the type width, which incurs undefined
|
||||
// behavior, but the conversion itself is undefined in that case, so
|
||||
// whatever the compiler decides to do is fine.
|
||||
else {
|
||||
return sign * (significand << (exponent - significandBits));
|
||||
}
|
||||
return __fixint(a);
|
||||
}
|
||||
|
@ -6,40 +6,21 @@
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixdfti for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
#define DOUBLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
/* Returns: convert a to a signed long long, rounding toward zero. */
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* su_int is a 32 bit integral type
|
||||
* value in double is representable in ti_int (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
typedef ti_int fixint_t;
|
||||
typedef tu_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__fixdfti(double a)
|
||||
{
|
||||
double_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
|
||||
if (e < 0)
|
||||
return 0;
|
||||
ti_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31;
|
||||
ti_int r = 0x0010000000000000uLL | (0x000FFFFFFFFFFFFFuLL & fb.u.all);
|
||||
if (e > 52)
|
||||
r <<= (e - 52);
|
||||
else
|
||||
r >>= (52 - e);
|
||||
return (r ^ s) - s;
|
||||
__fixdfti(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
||||
|
@ -1,43 +1,23 @@
|
||||
/* ===-- fixsfdi.c - Implement __fixsfdi -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixsfdi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: convert a to a signed long long, rounding toward zero. */
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* su_int is a 32 bit integral type
|
||||
* value in float is representable in di_int (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
ARM_EABI_FNALIAS(f2lz, fixsfdi)
|
||||
|
||||
typedef di_int fixint_t;
|
||||
typedef du_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixsfdi(float a)
|
||||
{
|
||||
float_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u & 0x7F800000) >> 23) - 127;
|
||||
if (e < 0)
|
||||
return 0;
|
||||
di_int s = (si_int)(fb.u & 0x80000000) >> 31;
|
||||
di_int r = (fb.u & 0x007FFFFF) | 0x00800000;
|
||||
if (e > 23)
|
||||
r <<= (e - 23);
|
||||
else
|
||||
r >>= (23 - e);
|
||||
return (r ^ s) - s;
|
||||
__fixsfdi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
@ -1,47 +1,22 @@
|
||||
//===-- lib/fixsfsi.c - Single-precision -> integer conversion ----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements single-precision to integer conversion for the
|
||||
// compiler-rt library. No range checking is performed; the behavior of this
|
||||
// conversion is undefined for out of range values in the C standard.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/* ===-- fixsfsi.c - Implement __fixsfsi -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
typedef si_int fixint_t;
|
||||
typedef su_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
ARM_EABI_FNALIAS(f2iz, fixsfsi)
|
||||
|
||||
COMPILER_RT_ABI int
|
||||
COMPILER_RT_ABI si_int
|
||||
__fixsfsi(fp_t a) {
|
||||
// Break a into sign, exponent, significand
|
||||
const rep_t aRep = toRep(a);
|
||||
const rep_t aAbs = aRep & absMask;
|
||||
const int sign = aRep & signBit ? -1 : 1;
|
||||
const int exponent = (aAbs >> significandBits) - exponentBias;
|
||||
const rep_t significand = (aAbs & significandMask) | implicitBit;
|
||||
|
||||
// If 0 < exponent < significandBits, right shift to get the result.
|
||||
if ((unsigned int)exponent < significandBits) {
|
||||
return sign * (significand >> (significandBits - exponent));
|
||||
}
|
||||
|
||||
// If exponent is negative, the result is zero.
|
||||
else if (exponent < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If significandBits < exponent, left shift to get the result. This shift
|
||||
// may end up being larger than the type width, which incurs undefined
|
||||
// behavior, but the conversion itself is undefined in that case, so
|
||||
// whatever the compiler decides to do is fine.
|
||||
else {
|
||||
return sign * (significand << (exponent - significandBits));
|
||||
}
|
||||
return __fixint(a);
|
||||
}
|
||||
|
@ -6,40 +6,21 @@
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixsfti for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
/* Returns: convert a to a signed long long, rounding toward zero. */
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* su_int is a 32 bit integral type
|
||||
* value in float is representable in ti_int (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
typedef ti_int fixint_t;
|
||||
typedef tu_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__fixsfti(float a)
|
||||
{
|
||||
float_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u & 0x7F800000) >> 23) - 127;
|
||||
if (e < 0)
|
||||
return 0;
|
||||
ti_int s = (si_int)(fb.u & 0x80000000) >> 31;
|
||||
ti_int r = (fb.u & 0x007FFFFF) | 0x00800000;
|
||||
if (e > 23)
|
||||
r <<= (e - 23);
|
||||
else
|
||||
r >>= (23 - e);
|
||||
return (r ^ s) - s;
|
||||
__fixsfti(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
||||
|
23
contrib/compiler-rt/lib/builtins/fixtfdi.c
Normal file
23
contrib/compiler-rt/lib/builtins/fixtfdi.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* ===-- fixtfdi.c - Implement __fixtfdi -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef di_int fixint_t;
|
||||
typedef du_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixtfdi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
#endif
|
23
contrib/compiler-rt/lib/builtins/fixtfsi.c
Normal file
23
contrib/compiler-rt/lib/builtins/fixtfsi.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* ===-- fixtfsi.c - Implement __fixtfsi -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef si_int fixint_t;
|
||||
typedef su_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__fixtfsi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
#endif
|
23
contrib/compiler-rt/lib/builtins/fixtfti.c
Normal file
23
contrib/compiler-rt/lib/builtins/fixtfti.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* ===-- fixtfti.c - Implement __fixtfti -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef ti_int fixint_t;
|
||||
typedef tu_int fixuint_t;
|
||||
#include "fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__fixtfti(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
#endif
|
@ -6,42 +6,16 @@
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixunsdfdi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: convert a to a unsigned long long, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* du_int is a 64 bit integral type
|
||||
* value in double is representable in du_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
#define DOUBLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
typedef du_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
ARM_EABI_FNALIAS(d2ulz, fixunsdfdi)
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunsdfdi(double a)
|
||||
{
|
||||
double_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
|
||||
if (e < 0 || (fb.u.s.high & 0x80000000))
|
||||
return 0;
|
||||
udwords r;
|
||||
r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
|
||||
r.s.low = fb.u.s.low;
|
||||
if (e > 52)
|
||||
r.all <<= (e - 52);
|
||||
else
|
||||
r.all >>= (52 - e);
|
||||
return r.all;
|
||||
__fixunsdfdi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
@ -6,39 +6,16 @@
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixunsdfsi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: convert a to a unsigned int, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* su_int is a 32 bit integral type
|
||||
* value in double is representable in su_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
#define DOUBLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
typedef su_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
ARM_EABI_FNALIAS(d2uiz, fixunsdfsi)
|
||||
|
||||
COMPILER_RT_ABI su_int
|
||||
__fixunsdfsi(double a)
|
||||
{
|
||||
double_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
|
||||
if (e < 0 || (fb.u.s.high & 0x80000000))
|
||||
return 0;
|
||||
return (
|
||||
0x80000000u |
|
||||
((fb.u.s.high & 0x000FFFFF) << 11) |
|
||||
(fb.u.s.low >> 21)
|
||||
) >> (31 - e);
|
||||
__fixunsdfsi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
@ -6,42 +6,18 @@
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixunsdfti for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a unsigned long long, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* tu_int is a 64 bit integral type
|
||||
* value in double is representable in tu_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
#define DOUBLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
typedef tu_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI tu_int
|
||||
__fixunsdfti(double a)
|
||||
{
|
||||
double_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
|
||||
if (e < 0 || (fb.u.s.high & 0x80000000))
|
||||
return 0;
|
||||
tu_int r = 0x0010000000000000uLL | (fb.u.all & 0x000FFFFFFFFFFFFFuLL);
|
||||
if (e > 52)
|
||||
r <<= (e - 52);
|
||||
else
|
||||
r >>= (52 - e);
|
||||
return r;
|
||||
__fixunsdftti(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
||||
|
@ -6,39 +6,16 @@
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixunssfdi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
/* Returns: convert a to a unsigned long long, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* du_int is a 64 bit integral type
|
||||
* value in float is representable in du_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
typedef du_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
ARM_EABI_FNALIAS(f2ulz, fixunssfdi)
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunssfdi(float a)
|
||||
{
|
||||
float_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u & 0x7F800000) >> 23) - 127;
|
||||
if (e < 0 || (fb.u & 0x80000000))
|
||||
return 0;
|
||||
du_int r = (fb.u & 0x007FFFFF) | 0x00800000;
|
||||
if (e > 23)
|
||||
r <<= (e - 23);
|
||||
else
|
||||
r >>= (23 - e);
|
||||
return r;
|
||||
__fixunssfdi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
@ -12,34 +12,14 @@
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Returns: convert a to a unsigned int, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* su_int is a 32 bit integral type
|
||||
* value in float is representable in su_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
typedef su_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
ARM_EABI_FNALIAS(f2uiz, fixunssfsi)
|
||||
|
||||
COMPILER_RT_ABI su_int
|
||||
__fixunssfsi(float a)
|
||||
{
|
||||
float_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u & 0x7F800000) >> 23) - 127;
|
||||
if (e < 0 || (fb.u & 0x80000000))
|
||||
return 0;
|
||||
su_int r = (fb.u & 0x007FFFFF) | 0x00800000;
|
||||
if (e > 23)
|
||||
r <<= (e - 23);
|
||||
else
|
||||
r >>= (23 - e);
|
||||
return r;
|
||||
__fixunssfsi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
@ -12,36 +12,12 @@
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a unsigned long long, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* tu_int is a 64 bit integral type
|
||||
* value in float is representable in tu_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
#if defined(CRT_HAS_128BIT)
|
||||
typedef tu_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI tu_int
|
||||
__fixunssfti(float a)
|
||||
{
|
||||
float_bits fb;
|
||||
fb.f = a;
|
||||
int e = ((fb.u & 0x7F800000) >> 23) - 127;
|
||||
if (e < 0 || (fb.u & 0x80000000))
|
||||
return 0;
|
||||
tu_int r = (fb.u & 0x007FFFFF) | 0x00800000;
|
||||
if (e > 23)
|
||||
r <<= (e - 23);
|
||||
else
|
||||
r >>= (23 - e);
|
||||
return r;
|
||||
__fixunssfti(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
||||
#endif
|
||||
|
22
contrib/compiler-rt/lib/builtins/fixunstfdi.c
Normal file
22
contrib/compiler-rt/lib/builtins/fixunstfdi.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* ===-- fixunstfdi.c - Implement __fixunstfdi -----------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef du_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunstfdi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
#endif
|
22
contrib/compiler-rt/lib/builtins/fixunstfsi.c
Normal file
22
contrib/compiler-rt/lib/builtins/fixunstfsi.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef su_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI su_int
|
||||
__fixunstfsi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
#endif
|
22
contrib/compiler-rt/lib/builtins/fixunstfti.c
Normal file
22
contrib/compiler-rt/lib/builtins/fixunstfti.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef tu_int fixuint_t;
|
||||
#include "fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI tu_int
|
||||
__fixunstfti(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
#endif
|
@ -38,6 +38,8 @@ __fixunsxfdi(long double a)
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
return 0;
|
||||
if ((unsigned)e > sizeof(du_int) * CHAR_BIT)
|
||||
return ~(du_int)0;
|
||||
return fb.u.low.all >> (63 - e);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* su_int is a 32 bit integral type
|
||||
* value in long double is representable in su_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
@ -38,6 +37,8 @@ __fixunsxfsi(long double a)
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
return 0;
|
||||
if ((unsigned)e > sizeof(su_int) * CHAR_BIT)
|
||||
return ~(su_int)0;
|
||||
return fb.u.low.s.high >> (31 - e);
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,8 @@
|
||||
*/
|
||||
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* tu_int is a 64 bit integral type
|
||||
* tu_int is a 128 bit integral type
|
||||
* value in long double is representable in tu_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
@ -38,6 +37,8 @@ __fixunsxfti(long double a)
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
return 0;
|
||||
if ((unsigned)e > sizeof(tu_int) * CHAR_BIT)
|
||||
return ~(tu_int)0;
|
||||
tu_int r = fb.u.low.all;
|
||||
if (e > 63)
|
||||
r <<= (e - 63);
|
||||
|
@ -19,7 +19,7 @@
|
||||
/* Returns: convert a to a signed long long, rounding toward zero. */
|
||||
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* su_int is a 32 bit integral type
|
||||
* di_int is a 64 bit integral type
|
||||
* value in long double is representable in di_int (no range checking performed)
|
||||
*/
|
||||
|
||||
@ -30,11 +30,15 @@
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixxfdi(long double a)
|
||||
{
|
||||
const di_int di_max = (di_int)((~(du_int)0) / 2);
|
||||
const di_int di_min = -di_max - 1;
|
||||
long_double_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0)
|
||||
return 0;
|
||||
if ((unsigned)e >= sizeof(di_int) * CHAR_BIT)
|
||||
return a > 0 ? di_max : di_min;
|
||||
di_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
|
||||
di_int r = fb.u.low.all;
|
||||
r = (du_int)r >> (63 - e);
|
||||
|
@ -19,8 +19,8 @@
|
||||
/* Returns: convert a to a signed long long, rounding toward zero. */
|
||||
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* su_int is a 32 bit integral type
|
||||
* value in long double is representable in ti_int (no range checking performed)
|
||||
* ti_int is a 128 bit integral type
|
||||
* value in long double is representable in ti_int
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
@ -30,6 +30,8 @@
|
||||
COMPILER_RT_ABI ti_int
|
||||
__fixxfti(long double a)
|
||||
{
|
||||
const ti_int ti_max = (ti_int)((~(tu_int)0) / 2);
|
||||
const ti_int ti_min = -ti_max - 1;
|
||||
long_double_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
@ -37,6 +39,8 @@ __fixxfti(long double a)
|
||||
return 0;
|
||||
ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
|
||||
ti_int r = fb.u.low.all;
|
||||
if ((unsigned)e >= sizeof(ti_int) * CHAR_BIT)
|
||||
return a > 0 ? ti_max : ti_min;
|
||||
if (e > 63)
|
||||
r <<= (e - 63);
|
||||
else
|
||||
|
41
contrib/compiler-rt/lib/builtins/fp_fixint_impl.inc
Normal file
41
contrib/compiler-rt/lib/builtins/fp_fixint_impl.inc
Normal file
@ -0,0 +1,41 @@
|
||||
//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements float to integer conversion for the
|
||||
// compiler-rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "fp_lib.h"
|
||||
|
||||
static inline fixint_t __fixint(fp_t a) {
|
||||
const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2);
|
||||
const fixint_t fixint_min = -fixint_max - 1;
|
||||
// Break a into sign, exponent, significand
|
||||
const rep_t aRep = toRep(a);
|
||||
const rep_t aAbs = aRep & absMask;
|
||||
const fixint_t sign = aRep & signBit ? -1 : 1;
|
||||
const int exponent = (aAbs >> significandBits) - exponentBias;
|
||||
const rep_t significand = (aAbs & significandMask) | implicitBit;
|
||||
|
||||
// If exponent is negative, the result is zero.
|
||||
if (exponent < 0)
|
||||
return 0;
|
||||
|
||||
// If the value is too large for the integer type, saturate.
|
||||
if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT)
|
||||
return sign == 1 ? fixint_max : fixint_min;
|
||||
|
||||
// If 0 <= exponent < significandBits, right shift to get the result.
|
||||
// Otherwise, shift left.
|
||||
if (exponent < significandBits)
|
||||
return sign * (significand >> (significandBits - exponent));
|
||||
else
|
||||
return sign * ((fixint_t)significand << (exponent - significandBits));
|
||||
}
|
39
contrib/compiler-rt/lib/builtins/fp_fixuint_impl.inc
Normal file
39
contrib/compiler-rt/lib/builtins/fp_fixuint_impl.inc
Normal file
@ -0,0 +1,39 @@
|
||||
//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements float to unsigned integer conversion for the
|
||||
// compiler-rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "fp_lib.h"
|
||||
|
||||
static inline fixuint_t __fixuint(fp_t a) {
|
||||
// Break a into sign, exponent, significand
|
||||
const rep_t aRep = toRep(a);
|
||||
const rep_t aAbs = aRep & absMask;
|
||||
const int sign = aRep & signBit ? -1 : 1;
|
||||
const int exponent = (aAbs >> significandBits) - exponentBias;
|
||||
const rep_t significand = (aAbs & significandMask) | implicitBit;
|
||||
|
||||
// If either the value or the exponent is negative, the result is zero.
|
||||
if (sign == -1 || exponent < 0)
|
||||
return 0;
|
||||
|
||||
// If the value is too large for the integer type, saturate.
|
||||
if ((unsigned)exponent > sizeof(fixuint_t) * CHAR_BIT)
|
||||
return ~(fixuint_t)0;
|
||||
|
||||
// If 0 <= exponent < significandBits, right shift to get the result.
|
||||
// Otherwise, shift left.
|
||||
if (exponent < significandBits)
|
||||
return significand >> (significandBits - exponent);
|
||||
else
|
||||
return (fixuint_t)significand << (exponent - significandBits);
|
||||
}
|
@ -55,12 +55,18 @@ SRCF= absvdi2 \
|
||||
fixdfti \
|
||||
fixsfdi \
|
||||
fixsfti \
|
||||
fixtfdi \
|
||||
fixtfsi \
|
||||
fixtfti \
|
||||
fixunsdfdi \
|
||||
fixunsdfsi \
|
||||
fixunsdfti \
|
||||
fixunssfdi \
|
||||
fixunssfsi \
|
||||
fixunssfti \
|
||||
fixunstfdi \
|
||||
fixunstfsi \
|
||||
fixunstfti \
|
||||
fixunsxfdi \
|
||||
fixunsxfsi \
|
||||
fixunsxfti \
|
||||
|
Loading…
Reference in New Issue
Block a user