From fa094d17448636e707fbcd300c8ef5d84bd09548 Mon Sep 17 00:00:00 2001 From: Serge Vakulenko Date: Sun, 3 Jan 2016 00:21:39 -0800 Subject: [PATCH] libc: add missing functions __fixunssfsi() and __floatunsisf(). --- lib/libc/Makefile | 3 ++- src/libc/runtime/Makefile | 3 ++- src/libc/runtime/fixunssfsi.c | 45 ++++++++++++++++++++++++++++++++ src/libc/runtime/floatsisf.c | 2 -- src/libc/runtime/floatunsisf.c | 47 ++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/libc/runtime/fixunssfsi.c create mode 100644 src/libc/runtime/floatunsisf.c diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 7a32960..0874861 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -95,7 +95,8 @@ OBJS += creat.o ftime.o gethostid.o memccpy.o memchr.o \ # libc/runtime OBJS += addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \ - mulsf3.o negsf2.o subsf3.o sc_case.o + mulsf3.o negsf2.o subsf3.o sc_case.o fixunssfsi.o \ + floatunsisf.o all: ../libc.a diff --git a/src/libc/runtime/Makefile b/src/libc/runtime/Makefile index ccf3c79..ca39b36 100644 --- a/src/libc/runtime/Makefile +++ b/src/libc/runtime/Makefile @@ -20,7 +20,8 @@ include $(TOPSRC)/target.mk CFLAGS += ${DEFS} OBJS = addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \ - mulsf3.o negsf2.o subsf3.o sc_case.o + mulsf3.o negsf2.o subsf3.o sc_case.o fixunssfsi.o \ + floatunsisf.o all: ${OBJS} diff --git a/src/libc/runtime/fixunssfsi.c b/src/libc/runtime/fixunssfsi.c new file mode 100644 index 0000000..be0cde4 --- /dev/null +++ b/src/libc/runtime/fixunssfsi.c @@ -0,0 +1,45 @@ +/* ===-- fixunssfsi.c - Implement __fixunssfsi -----------------------------=== + * + * 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 __fixunssfsi for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ +#define SINGLE_PRECISION +#include "fp_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 */ + +uint32_t +__fixunssfsi(fp_t a) +{ + union { fp_t f; rep_t u; } fb; + fb.f = a; + + int e = ((fb.u & 0x7F800000) >> 23) - 127; + if (e < 0 || (fb.u & 0x80000000)) + return 0; + + rep_t r = (fb.u & 0x007FFFFF) | 0x00800000; + if (e > 23) + r <<= (e - 23); + else + r >>= (23 - e); + return r; +} diff --git a/src/libc/runtime/floatsisf.c b/src/libc/runtime/floatsisf.c index 5a1277a..365e78a 100644 --- a/src/libc/runtime/floatsisf.c +++ b/src/libc/runtime/floatsisf.c @@ -16,8 +16,6 @@ #define SINGLE_PRECISION #include "fp_lib.h" -//#include "int_lib.h" - fp_t __floatsisf(int a) { diff --git a/src/libc/runtime/floatunsisf.c b/src/libc/runtime/floatunsisf.c new file mode 100644 index 0000000..a61066c --- /dev/null +++ b/src/libc/runtime/floatunsisf.c @@ -0,0 +1,47 @@ +//===-- lib/floatunsisf.c - uint -> single-precision 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 unsigned integer to single-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +#define SINGLE_PRECISION +#include "fp_lib.h" + +fp_t +__floatunsisf(unsigned int a) +{ + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) + return fromRep(0); + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clz(a); + rep_t result; + + // Shift a into the significand field, rounding if it is a right-shift + if (exponent <= significandBits) { + const int shift = significandBits - exponent; + result = (rep_t)a << shift ^ implicitBit; + } else { + const int shift = exponent - significandBits; + result = (rep_t)a >> shift ^ implicitBit; + rep_t round = (rep_t)a << (typeWidth - shift); + if (round > signBit) result++; + if (round == signBit) result += result & 1; + } + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + return fromRep(result); +}