Skip to content

Commit

Permalink
libc: add missing functions __fixunssfsi() and __floatunsisf().
Browse files Browse the repository at this point in the history
  • Loading branch information
sergev committed Jan 3, 2016
1 parent b7a3d6f commit fa094d1
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 4 deletions.
3 changes: 2 additions & 1 deletion lib/libc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion src/libc/runtime/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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}

Expand Down
45 changes: 45 additions & 0 deletions src/libc/runtime/fixunssfsi.c
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 0 additions & 2 deletions src/libc/runtime/floatsisf.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
#define SINGLE_PRECISION
#include "fp_lib.h"

//#include "int_lib.h"

fp_t
__floatsisf(int a)
{
Expand Down
47 changes: 47 additions & 0 deletions src/libc/runtime/floatunsisf.c
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit fa094d1

Please sign in to comment.