Move libclang into libc.

Catch all warnings.
This commit is contained in:
Serge
2022-05-27 00:20:07 -07:00
parent 9c50b5a97d
commit 4fdec2101b
58 changed files with 574 additions and 1903 deletions

1
.gitignore vendored
View File

@@ -26,3 +26,4 @@
*.img *.img
Makefile.user Makefile.user
TODO

View File

@@ -9,8 +9,7 @@ include $(TOPSRC)/target.mk
# Programs that live in subdirectories, and have makefiles of their own. # Programs that live in subdirectories, and have makefiles of their own.
# #
SUBDIR = startup-$(MACHINE) libc libm libutil libtermlib libcurses \ SUBDIR = startup-$(MACHINE) libc libm libutil libtermlib libcurses \
libvmf libwiznet libreadline libgpanel share cmd games man \ libvmf libwiznet libreadline libgpanel share cmd games man
libclang
all: $(SUBDIR) all: $(SUBDIR)

View File

@@ -5,7 +5,7 @@ CFLAGS += -Werror -Os
YACC = bison -y YACC = bison -y
YFLAGS = -d YFLAGS = -d
LIBS = -lm -lc -lclang LIBS = -lm -lc
FILES = awk.lx.o b.o main.o tran.o lib.o run.o parse.o proctab.o freeze.o FILES = awk.lx.o b.o main.o tran.o lib.o run.o parse.o proctab.o freeze.o
SOURCE = awk.def.h awk.g.y awk.lx.l b.c lib.c main.c parse.c \ SOURCE = awk.def.h awk.g.y awk.lx.l b.c lib.c main.c parse.c \
proc.c freeze.c run.c tran.c proc.c freeze.c run.c tran.c

View File

@@ -30,7 +30,7 @@ struct xx
{ INDIRECT, "indirect", "$("}, { INDIRECT, "indirect", "$("},
{ SUBSTR, "substr", "substr"}, { SUBSTR, "substr", "substr"},
{ INDEX, "sindex", "sindex"}, { INDEX, "sindex", "sindex"},
{ SPRINTF, "asprintf", "sprintf "}, { SPRINTF, "awksprintf", "sprintf "},
{ ADD, "arith", " + "}, { ADD, "arith", " + "},
{ MINUS, "arith", " - "}, { MINUS, "arith", " - "},
{ MULT, "arith", " * "}, { MULT, "arith", " * "},

View File

@@ -402,7 +402,7 @@ char *format(s,a) char *s; node *a;
return(buf); return(buf);
} }
obj asprintf1(a,n) node **a; obj awksprintf(a,n) node **a;
{ {
obj x; obj x;
node *y; node *y;
@@ -597,7 +597,7 @@ obj aprintf(a,n) node **a;
{ {
obj x; obj x;
x = asprintf1(a,n); x = awksprintf(a,n);
if (a[1]==NULL) { if (a[1]==NULL) {
printf("%s", x.optr->sval); printf("%s", x.optr->sval);
tempfree(x); tempfree(x);

View File

@@ -27,7 +27,7 @@ TOPSRC = $(shell cd ../..; pwd)
include $(TOPSRC)/target.mk include $(TOPSRC)/target.mk
DEFS = -Wall -Werror DEFS = -Wall -Werror
ALL = gen stdio stdlib string inet compat ${MACHINE} ALL = gen stdio stdlib string inet compat runtime ${MACHINE}
all: ../libc.a all: ../libc.a

View File

@@ -19,20 +19,30 @@ include $(TOPSRC)/target.mk
CFLAGS += ${DEFS} CFLAGS += ${DEFS}
OBJS = addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \ OBJS = adddf3.o \
mulsf3.o negsf2.o subsf3.o sc_case.o fixunssfsi.o \ addsf3.o \
floatunsisf.o divdf3.o \
divsf3.o \
all: ${OBJS} comparedf2.o \
comparesf2.o \
extendsfdf2.o \
fixdfsi.o \
fixsfsi.o \
floatsidf.o \
floatsisf.o \
floatunsisf.o \
fp_mode.o \
muldf3.o \
mulsf3.o \
subdf3.o \
subsf3.o \
truncdfsf2.o
runtime.a: ${OBJS}
@echo "buiding runtime.a"
@$(AR) cru runtime.a ${OBJS}
clean: clean:
rm -f *.a *.o *~ profiled/*.o tags rm -f *.a *.o *~ profiled/*.o tags
cleandir: clean cleandir: clean
rm -f .depend rm -f .depend
install: all
# cp ../libgcc.a ${DESTDIR}/lib/
# $(RANLIB) -t ${DESTDIR}/lib/libgcc.a
# cp libgcc_p.a ${DESTDIR}/lib/
# $(RANLIB) -t ${DESTDIR}/lib/libgcc_p.a

View File

@@ -20,13 +20,18 @@ Here is the specification for this library:
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc
Please note that the libgcc specification explicitly mentions actual types of
arguments and returned values being expressed with machine modes.
In some cases particular types such as "int", "unsigned", "long long", etc.
may be specified just as examples there.
Here is a synopsis of the contents of this library: Here is a synopsis of the contents of this library:
typedef int si_int; typedef int32_t si_int;
typedef unsigned su_int; typedef uint32_t su_int;
typedef long long di_int; typedef int64_t di_int;
typedef unsigned long long du_int; typedef uint64_t du_int;
// Integral bit manipulation // Integral bit manipulation
@@ -38,26 +43,27 @@ ti_int __ashrti3(ti_int a, si_int b); // a >> b arithmetic (sign fill)
di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill) di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill)
ti_int __lshrti3(ti_int a, si_int b); // a >> b logical (zero fill) ti_int __lshrti3(ti_int a, si_int b); // a >> b logical (zero fill)
si_int __clzsi2(si_int a); // count leading zeros int __clzsi2(si_int a); // count leading zeros
si_int __clzdi2(di_int a); // count leading zeros int __clzdi2(di_int a); // count leading zeros
si_int __clzti2(ti_int a); // count leading zeros int __clzti2(ti_int a); // count leading zeros
si_int __ctzsi2(si_int a); // count trailing zeros int __ctzsi2(si_int a); // count trailing zeros
si_int __ctzdi2(di_int a); // count trailing zeros int __ctzdi2(di_int a); // count trailing zeros
si_int __ctzti2(ti_int a); // count trailing zeros int __ctzti2(ti_int a); // count trailing zeros
si_int __ffsdi2(di_int a); // find least significant 1 bit int __ffssi2(si_int a); // find least significant 1 bit
si_int __ffsti2(ti_int a); // find least significant 1 bit int __ffsdi2(di_int a); // find least significant 1 bit
int __ffsti2(ti_int a); // find least significant 1 bit
si_int __paritysi2(si_int a); // bit parity int __paritysi2(si_int a); // bit parity
si_int __paritydi2(di_int a); // bit parity int __paritydi2(di_int a); // bit parity
si_int __parityti2(ti_int a); // bit parity int __parityti2(ti_int a); // bit parity
si_int __popcountsi2(si_int a); // bit population int __popcountsi2(si_int a); // bit population
si_int __popcountdi2(di_int a); // bit population int __popcountdi2(di_int a); // bit population
si_int __popcountti2(ti_int a); // bit population int __popcountti2(ti_int a); // bit population
uint32_t __bswapsi2(uint32_t a); // a byteswapped, arm only uint32_t __bswapsi2(uint32_t a); // a byteswapped
uint64_t __bswapdi2(uint64_t a); // a byteswapped, arm only uint64_t __bswapdi2(uint64_t a); // a byteswapped
// Integral arithmetic // Integral arithmetic
@@ -81,6 +87,8 @@ du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b u
tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); // a / b, *rem = a % b unsigned tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); // a / b, *rem = a % b unsigned
su_int __udivmodsi4(su_int a, su_int b, su_int* rem); // a / b, *rem = a % b unsigned su_int __udivmodsi4(su_int a, su_int b, su_int* rem); // a / b, *rem = a % b unsigned
si_int __divmodsi4(si_int a, si_int b, si_int* rem); // a / b, *rem = a % b signed si_int __divmodsi4(si_int a, si_int b, si_int* rem); // a / b, *rem = a % b signed
di_int __divmoddi4(di_int a, di_int b, di_int* rem); // a / b, *rem = a % b signed
ti_int __divmodti4(ti_int a, ti_int b, ti_int* rem); // a / b, *rem = a % b signed
@@ -168,10 +176,10 @@ long double __floatuntixf(tu_int a);
// Floating point raised to integer power // Floating point raised to integer power
float __powisf2( float a, si_int b); // a ^ b float __powisf2( float a, int b); // a ^ b
double __powidf2( double a, si_int b); // a ^ b double __powidf2( double a, int b); // a ^ b
long double __powixf2(long double a, si_int b); // a ^ b long double __powixf2(long double a, int b); // a ^ b
long double __powitf2(long double a, si_int b); // ppc only, a ^ b long double __powitf2(long double a, int b); // ppc only, a ^ b
// Complex arithmetic // Complex arithmetic
@@ -198,7 +206,7 @@ long double _Complex __divtc3(long double a, long double b,
// __clear_cache() is used to tell process that new instructions have been // __clear_cache() is used to tell process that new instructions have been
// written to an address range. Necessary on processors that do not have // written to an address range. Necessary on processors that do not have
// a unified instuction and data cache. // a unified instruction and data cache.
void __clear_cache(void* start, void* end); void __clear_cache(void* start, void* end);
// __enable_execute_stack() is used with nested functions when a trampoline // __enable_execute_stack() is used with nested functions when a trampoline
@@ -220,7 +228,9 @@ _Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,
// for use with some implementations of assert() in <assert.h> // for use with some implementations of assert() in <assert.h>
void __eprintf(const char* format, const char* assertion_expression, void __eprintf(const char* format, const char* assertion_expression,
const char* line, const char* file); const char* line, const char* file);
// for systems with emulated thread local storage
void* __emutls_get_address(struct __emutls_control*);
// Power PC specific functions // Power PC specific functions

View File

@@ -1,150 +1,24 @@
//===-- lib/addsf3.c - Single-precision addition ------------------*- C -*-===// //===-- lib/addsf3.c - Single-precision addition ------------------*- C -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Source Licenses. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file implements single-precision soft-float addition with the IEEE-754 // This file implements single-precision soft-float addition.
// default rounding (to nearest, ties to even).
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define SINGLE_PRECISION #define SINGLE_PRECISION
#include "fp_lib.h" #include "fp_add_impl.inc"
fp_t COMPILER_RT_ABI float __addsf3(float a, float b) { return __addXf3__(a, b); }
__addsf3(fp_t a, fp_t b)
{
rep_t aRep = toRep(a);
rep_t bRep = toRep(b);
const rep_t aAbs = aRep & absMask;
const rep_t bAbs = bRep & absMask;
// Detect if a or b is zero, infinity, or NaN. #if defined(__ARM_EABI__)
if (aAbs - 1U >= infRep - 1U || bAbs - 1U >= infRep - 1U) { #if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI float __aeabi_fadd(float a, float b) { return __addsf3(a, b); }
// NaN + anything = qNaN #else
if (aAbs > infRep) return fromRep(toRep(a) | quietBit); COMPILER_RT_ALIAS(__addsf3, __aeabi_fadd)
// anything + NaN = qNaN #endif
if (bAbs > infRep) return fromRep(toRep(b) | quietBit); #endif
if (aAbs == infRep) {
// +/-infinity + -/+infinity = qNaN
if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep);
// +/-infinity + anything remaining = +/- infinity
else return a;
}
// anything remaining + +/-infinity = +/-infinity
if (bAbs == infRep) return b;
// zero + anything = anything
if (!aAbs) {
// but we need to get the sign right for zero + zero
if (!bAbs) return fromRep(toRep(a) & toRep(b));
else return b;
}
// anything + zero = anything
if (!bAbs) return a;
}
// Swap a and b if necessary so that a has the larger absolute value.
if (bAbs > aAbs) {
const rep_t temp = aRep;
aRep = bRep;
bRep = temp;
}
// Extract the exponent and significand from the (possibly swapped) a and b.
int aExponent = aRep >> significandBits & maxExponent;
int bExponent = bRep >> significandBits & maxExponent;
rep_t aSignificand = aRep & significandMask;
rep_t bSignificand = bRep & significandMask;
// Normalize any denormals, and adjust the exponent accordingly.
if (aExponent == 0) aExponent = normalize(&aSignificand);
if (bExponent == 0) bExponent = normalize(&bSignificand);
// The sign of the result is the sign of the larger operand, a. If they
// have opposite signs, we are performing a subtraction; otherwise addition.
const rep_t resultSign = aRep & signBit;
const int subtraction = ((aRep ^ bRep) & signBit) != 0;
// Shift the significands to give us round, guard and sticky, and or in the
// implicit significand bit. (If we fell through from the denormal path it
// was already set by normalize( ), but setting it twice won't hurt
// anything.)
aSignificand = (aSignificand | implicitBit) << 3;
bSignificand = (bSignificand | implicitBit) << 3;
// Shift the significand of b by the difference in exponents, with a sticky
// bottom bit to get rounding correct.
const unsigned int align = aExponent - bExponent;
if (align) {
if (align < typeWidth) {
const int sticky = (bSignificand << (typeWidth - align)) != 0;
bSignificand = bSignificand >> align | sticky;
} else {
bSignificand = 1; // sticky; b is known to be non-zero.
}
}
if (subtraction) {
aSignificand -= bSignificand;
// If a == -b, return +zero.
if (aSignificand == 0) return fromRep(0);
// If partial cancellation occured, we need to left-shift the result
// and adjust the exponent:
if (aSignificand < implicitBit << 3) {
const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3);
aSignificand <<= shift;
aExponent -= shift;
}
}
else /* addition */ {
aSignificand += bSignificand;
// If the addition carried up, we need to right-shift the result and
// adjust the exponent:
if (aSignificand & implicitBit << 4) {
const int sticky = aSignificand & 1;
aSignificand = aSignificand >> 1 | sticky;
aExponent += 1;
}
}
// If we have overflowed the type, return +/- infinity:
if (aExponent >= maxExponent) return fromRep(infRep | resultSign);
if (aExponent <= 0) {
// Result is denormal before rounding; the exponent is zero and we
// need to shift the significand.
const int shift = 1 - aExponent;
const int sticky = (aSignificand << (typeWidth - shift)) != 0;
aSignificand = aSignificand >> shift | sticky;
aExponent = 0;
}
// Low three bits are round, guard, and sticky.
const int roundGuardSticky = aSignificand & 0x7;
// Shift the significand into place, and mask off the implicit bit.
rep_t result = aSignificand >> 3 & significandMask;
// Insert the exponent and sign.
result |= (rep_t)aExponent << significandBits;
result |= resultSign;
// Final rounding. The result may overflow to infinity, but that is the
// correct result in that case.
if (roundGuardSticky > 0x4) result++;
if (roundGuardSticky == 0x4) result += result & 1;
return fromRep(result);
}

View File

@@ -1,9 +1,8 @@
//===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===// //===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Source Licenses. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
@@ -40,104 +39,113 @@
#define SINGLE_PRECISION #define SINGLE_PRECISION
#include "fp_lib.h" #include "fp_lib.h"
enum LE_RESULT { enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 };
LE_LESS = -1,
LE_EQUAL = 0,
LE_GREATER = 1,
LE_UNORDERED = 1
};
enum LE_RESULT COMPILER_RT_ABI enum LE_RESULT __lesf2(fp_t a, fp_t b) {
__lesf2(fp_t a, fp_t b)
{
const srep_t aInt = toRep(a);
const srep_t bInt = toRep(b);
const rep_t aAbs = aInt & absMask;
const rep_t bAbs = bInt & absMask;
// If either a or b is NaN, they are unordered. const srep_t aInt = toRep(a);
if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; const srep_t bInt = toRep(b);
const rep_t aAbs = aInt & absMask;
const rep_t bAbs = bInt & absMask;
// If a and b are both zeros, they are equal. // If either a or b is NaN, they are unordered.
if ((aAbs | bAbs) == 0) return LE_EQUAL; if (aAbs > infRep || bAbs > infRep)
return LE_UNORDERED;
// If at least one of a and b is positive, we get the same result comparing // If a and b are both zeros, they are equal.
// a and b as signed integers as we would with a fp_ting-point compare. if ((aAbs | bAbs) == 0)
if ((aInt & bInt) >= 0) { return LE_EQUAL;
if (aInt < bInt) return LE_LESS;
else if (aInt == bInt) return LE_EQUAL;
else return LE_GREATER;
}
// Otherwise, both are negative, so we need to flip the sense of the // If at least one of a and b is positive, we get the same result comparing
// comparison to get the correct result. (This assumes a twos- or ones- // a and b as signed integers as we would with a fp_ting-point compare.
// complement integer representation; if integers are represented in a if ((aInt & bInt) >= 0) {
// sign-magnitude representation, then this flip is incorrect). if (aInt < bInt)
else { return LE_LESS;
if (aInt > bInt) return LE_LESS; else if (aInt == bInt)
else if (aInt == bInt) return LE_EQUAL; return LE_EQUAL;
else return LE_GREATER; else
} return LE_GREATER;
}
// Otherwise, both are negative, so we need to flip the sense of the
// comparison to get the correct result. (This assumes a twos- or ones-
// complement integer representation; if integers are represented in a
// sign-magnitude representation, then this flip is incorrect).
else {
if (aInt > bInt)
return LE_LESS;
else if (aInt == bInt)
return LE_EQUAL;
else
return LE_GREATER;
}
} }
#if defined(__ELF__)
// Alias for libgcc compatibility
COMPILER_RT_ALIAS(__lesf2, __cmpsf2)
#endif
COMPILER_RT_ALIAS(__lesf2, __eqsf2)
COMPILER_RT_ALIAS(__lesf2, __ltsf2)
COMPILER_RT_ALIAS(__lesf2, __nesf2)
enum GE_RESULT { enum GE_RESULT {
GE_LESS = -1, GE_LESS = -1,
GE_EQUAL = 0, GE_EQUAL = 0,
GE_GREATER = 1, GE_GREATER = 1,
GE_UNORDERED = -1 // Note: different from LE_UNORDERED GE_UNORDERED = -1 // Note: different from LE_UNORDERED
}; };
enum GE_RESULT COMPILER_RT_ABI enum GE_RESULT __gesf2(fp_t a, fp_t b) {
__gesf2(fp_t a, fp_t b)
{
const srep_t aInt = toRep(a);
const srep_t bInt = toRep(b);
const rep_t aAbs = aInt & absMask;
const rep_t bAbs = bInt & absMask;
if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; const srep_t aInt = toRep(a);
if ((aAbs | bAbs) == 0) return GE_EQUAL; const srep_t bInt = toRep(b);
if ((aInt & bInt) >= 0) { const rep_t aAbs = aInt & absMask;
if (aInt < bInt) return GE_LESS; const rep_t bAbs = bInt & absMask;
else if (aInt == bInt) return GE_EQUAL;
else return GE_GREATER; if (aAbs > infRep || bAbs > infRep)
} else { return GE_UNORDERED;
if (aInt > bInt) return GE_LESS; if ((aAbs | bAbs) == 0)
else if (aInt == bInt) return GE_EQUAL; return GE_EQUAL;
else return GE_GREATER; if ((aInt & bInt) >= 0) {
} if (aInt < bInt)
return GE_LESS;
else if (aInt == bInt)
return GE_EQUAL;
else
return GE_GREATER;
} else {
if (aInt > bInt)
return GE_LESS;
else if (aInt == bInt)
return GE_EQUAL;
else
return GE_GREATER;
}
} }
int COMPILER_RT_ALIAS(__gesf2, __gtsf2)
__unordsf2(fp_t a, fp_t b)
{ COMPILER_RT_ABI int
__unordsf2(fp_t a, fp_t b) {
const rep_t aAbs = toRep(a) & absMask; const rep_t aAbs = toRep(a) & absMask;
const rep_t bAbs = toRep(b) & absMask; const rep_t bAbs = toRep(b) & absMask;
return aAbs > infRep || bAbs > infRep; return aAbs > infRep || bAbs > infRep;
} }
// The following are alternative names for the preceeding routines. #if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI int __aeabi_fcmpun(fp_t a, fp_t b) { return __unordsf2(a, b); }
#else
COMPILER_RT_ALIAS(__unordsf2, __aeabi_fcmpun)
#endif
#endif
enum LE_RESULT #if defined(_WIN32) && !defined(__MINGW32__)
__eqsf2(fp_t a, fp_t b) // The alias mechanism doesn't work on Windows except for MinGW, so emit
{ // wrapper functions.
return __lesf2(a, b); int __eqsf2(fp_t a, fp_t b) { return __lesf2(a, b); }
} int __ltsf2(fp_t a, fp_t b) { return __lesf2(a, b); }
int __nesf2(fp_t a, fp_t b) { return __lesf2(a, b); }
enum LE_RESULT int __gtsf2(fp_t a, fp_t b) { return __gesf2(a, b); }
__ltsf2(fp_t a, fp_t b) #endif
{
return __lesf2(a, b);
}
enum LE_RESULT
__nesf2(fp_t a, fp_t b)
{
return __lesf2(a, b);
}
enum GE_RESULT
__gtsf2(fp_t a, fp_t b)
{
return __gesf2(a, b);
}

View File

@@ -1,165 +1,30 @@
//===-- lib/divsf3.c - Single-precision division ------------------*- C -*-===// //===-- lib/divsf3.c - Single-precision division ------------------*- C -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Source Licenses. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file implements single-precision soft-float division // This file implements single-precision soft-float division
// with the IEEE-754 default rounding (to nearest, ties to even). // with the IEEE-754 default rounding (to nearest, ties to even).
// //
// For simplicity, this implementation currently flushes denormals to zero.
// It should be a fairly straightforward exercise to implement gradual
// underflow with correct rounding.
//
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define SINGLE_PRECISION #define SINGLE_PRECISION
#include "fp_lib.h"
fp_t #define NUMBER_OF_HALF_ITERATIONS 0
__divsf3(fp_t a, fp_t b) #define NUMBER_OF_FULL_ITERATIONS 3
{ #define USE_NATIVE_FULL_ITERATIONS
const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit;
rep_t aSignificand = toRep(a) & significandMask; #include "fp_div_impl.inc"
rep_t bSignificand = toRep(b) & significandMask;
int scale = 0;
// Detect if a or b is zero, denormal, infinity, or NaN. COMPILER_RT_ABI fp_t __divsf3(fp_t a, fp_t b) { return __divXf3__(a, b); }
if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {
const rep_t aAbs = toRep(a) & absMask; #if defined(__ARM_EABI__)
const rep_t bAbs = toRep(b) & absMask; #if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_fdiv(fp_t a, fp_t b) { return __divsf3(a, b); }
// NaN / anything = qNaN #else
if (aAbs > infRep) return fromRep(toRep(a) | quietBit); COMPILER_RT_ALIAS(__divsf3, __aeabi_fdiv)
// anything / NaN = qNaN #endif
if (bAbs > infRep) return fromRep(toRep(b) | quietBit); #endif
if (aAbs == infRep) {
// infinity / infinity = NaN
if (bAbs == infRep) return fromRep(qnanRep);
// infinity / anything else = +/- infinity
else return fromRep(aAbs | quotientSign);
}
// anything else / infinity = +/- 0
if (bAbs == infRep) return fromRep(quotientSign);
if (!aAbs) {
// zero / zero = NaN
if (!bAbs) return fromRep(qnanRep);
// zero / anything else = +/- zero
else return fromRep(quotientSign);
}
// anything else / zero = +/- infinity
if (!bAbs) return fromRep(infRep | quotientSign);
// one or both of a or b is denormal, the other (if applicable) is a
// normal number. Renormalize one or both of a and b, and set scale to
// include the necessary exponent adjustment.
if (aAbs < implicitBit) scale += normalize(&aSignificand);
if (bAbs < implicitBit) scale -= normalize(&bSignificand);
}
// Or in the implicit significand bit. (If we fell through from the
// denormal path it was already set by normalize( ), but setting it twice
// won't hurt anything.)
aSignificand |= implicitBit;
bSignificand |= implicitBit;
int quotientExponent = aExponent - bExponent + scale;
// Align the significand of b as a Q31 fixed-point number in the range
// [1, 2.0) and get a Q32 approximate reciprocal using a small minimax
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// is accurate to about 3.5 binary digits.
uint32_t q31b = bSignificand << 8;
uint32_t reciprocal = UINT32_C(0x7504f333) - q31b;
// Now refine the reciprocal estimate using a Newton-Raphson iteration:
//
// x1 = x0 * (2 - x0 * b)
//
// This doubles the number of correct binary digits in the approximation
// with each iteration, so after three iterations, we have about 28 binary
// digits of accuracy.
uint32_t correction;
correction = -((uint64_t)reciprocal * q31b >> 32);
reciprocal = (uint64_t)reciprocal * correction >> 31;
correction = -((uint64_t)reciprocal * q31b >> 32);
reciprocal = (uint64_t)reciprocal * correction >> 31;
correction = -((uint64_t)reciprocal * q31b >> 32);
reciprocal = (uint64_t)reciprocal * correction >> 31;
// Exhaustive testing shows that the error in reciprocal after three steps
// is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our
// expectations. We bump the reciprocal by a tiny value to force the error
// to be strictly positive (in the range [0x1.4fdfp-37,0x1.287246p-29], to
// be specific). This also causes 1/1 to give a sensible approximation
// instead of zero (due to overflow).
reciprocal -= 2;
// The numerical reciprocal is accurate to within 2^-28, lies in the
// interval [0x1.000000eep-1, 0x1.fffffffcp-1], and is strictly smaller
// than the true reciprocal of b. Multiplying a by this reciprocal thus
// gives a numerical q = a/b in Q24 with the following properties:
//
// 1. q < a/b
// 2. q is in the interval [0x1.000000eep-1, 0x1.fffffffcp0)
// 3. the error in q is at most 2^-24 + 2^-27 -- the 2^24 term comes
// from the fact that we truncate the product, and the 2^27 term
// is the error in the reciprocal of b scaled by the maximum
// possible value of a. As a consequence of this error bound,
// either q or nextafter(q) is the correctly rounded
rep_t quotient = (uint64_t)reciprocal*(aSignificand << 1) >> 32;
// Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
// In either case, we are going to compute a residual of the form
//
// r = a - q*b
//
// We know from the construction of q that r satisfies:
//
// 0 <= r < ulp(q)*b
//
// if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we
// already have the correct result. The exact halfway case cannot occur.
// We also take this time to right shift quotient if it falls in the [1,2)
// range and adjust the exponent accordingly.
rep_t residual;
if (quotient < (implicitBit << 1)) {
residual = (aSignificand << 24) - quotient * bSignificand;
quotientExponent--;
} else {
quotient >>= 1;
residual = (aSignificand << 23) - quotient * bSignificand;
}
const int writtenExponent = quotientExponent + exponentBias;
if (writtenExponent >= maxExponent) {
// If we have overflowed the exponent, return infinity.
return fromRep(infRep | quotientSign);
}
else if (writtenExponent < 1) {
// Flush denormals to zero. In the future, it would be nice to add
// code to round them correctly.
return fromRep(quotientSign);
}
else {
int round = (residual << 1) > bSignificand;
// Clear the implicit bit
rep_t absResult = quotient & significandMask;
// Insert the exponent
absResult |= (rep_t)writtenExponent << significandBits;
// Round
absResult += round;
// Insert the sign and return
return fromRep(absResult | quotientSign);
}
}

View File

@@ -1,46 +1,23 @@
//===-- lib/fixsfsi.c - Single-precision -> integer conversion ----*- C -*-===// //===-- fixsfsi.c - Implement __fixsfsi -----------------------------------===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// 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.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define SINGLE_PRECISION #define SINGLE_PRECISION
#include "fp_lib.h" #include "fp_lib.h"
typedef si_int fixint_t;
typedef su_int fixuint_t;
#include "fp_fixint_impl.inc"
int COMPILER_RT_ABI si_int __fixsfsi(fp_t a) { return __fixint(a); }
__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 defined(__ARM_EABI__)
if ((unsigned int)exponent < significandBits) { #if defined(COMPILER_RT_ARMHF_TARGET)
return sign * (significand >> (significandBits - exponent)); AEABI_RTABI si_int __aeabi_f2iz(fp_t a) { return __fixsfsi(a); }
} #else
COMPILER_RT_ALIAS(__fixsfsi, __aeabi_f2iz)
// If exponent is negative, the result is zero. #endif
else if (exponent < 0) { #endif
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));
}
}

View File

@@ -1,45 +0,0 @@
/* ===-- 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;
}

View File

@@ -1,9 +1,8 @@
//===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===// //===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Source Licenses. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
@@ -16,40 +15,51 @@
#define SINGLE_PRECISION #define SINGLE_PRECISION
#include "fp_lib.h" #include "fp_lib.h"
fp_t #include "int_lib.h"
__floatsisf(int a)
{
const int aWidth = sizeof a * CHAR_BIT;
// Handle zero as a special case to protect clz COMPILER_RT_ABI fp_t __floatsisf(int a) {
if (a == 0)
return fromRep(0);
// All other cases begin by extracting the sign and absolute value of a const int aWidth = sizeof a * CHAR_BIT;
rep_t sign = 0;
if (a < 0) {
sign = signBit;
a = -a;
}
// Exponent of (fp_t)a is the width of abs(a). // Handle zero as a special case to protect clz
const int exponent = (aWidth - 1) - __builtin_clz(a); if (a == 0)
rep_t result; return fromRep(0);
// Shift a into the significand field, rounding if it is a right-shift // All other cases begin by extracting the sign and absolute value of a
if (exponent <= significandBits) { rep_t sign = 0;
const int shift = significandBits - exponent; if (a < 0) {
result = (rep_t)a << shift ^ implicitBit; sign = signBit;
} else { a = -a;
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 // Exponent of (fp_t)a is the width of abs(a).
result += (rep_t)(exponent + exponentBias) << significandBits; const int exponent = (aWidth - 1) - __builtin_clz(a);
// Insert the sign bit and return rep_t result;
return fromRep(result | sign);
// 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;
// Insert the sign bit and return
return fromRep(result | sign);
} }
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_i2f(int a) { return __floatsisf(a); }
#else
COMPILER_RT_ALIAS(__floatsisf, __aeabi_i2f)
#endif
#endif

View File

@@ -1,9 +1,8 @@
//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===// //===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Source Licenses. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
@@ -16,32 +15,43 @@
#define SINGLE_PRECISION #define SINGLE_PRECISION
#include "fp_lib.h" #include "fp_lib.h"
fp_t #include "int_lib.h"
__floatunsisf(unsigned int a)
{
const int aWidth = sizeof a * CHAR_BIT;
// Handle zero as a special case to protect clz COMPILER_RT_ABI fp_t __floatunsisf(unsigned int a) {
if (a == 0)
return fromRep(0);
// Exponent of (fp_t)a is the width of abs(a). const int aWidth = sizeof a * CHAR_BIT;
const int exponent = (aWidth - 1) - __builtin_clz(a);
rep_t result;
// Shift a into the significand field, rounding if it is a right-shift // Handle zero as a special case to protect clz
if (exponent <= significandBits) { if (a == 0)
const int shift = significandBits - exponent; return fromRep(0);
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 // Exponent of (fp_t)a is the width of abs(a).
result += (rep_t)(exponent + exponentBias) << significandBits; const int exponent = (aWidth - 1) - __builtin_clz(a);
return fromRep(result); 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);
} }
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) { return __floatunsisf(a); }
#else
COMPILER_RT_ALIAS(__floatunsisf, __aeabi_ui2f)
#endif
#endif

View File

@@ -1,9 +1,8 @@
//===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===// //===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Source Licenses. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
@@ -12,60 +11,72 @@
// many useful constants and utility routines that are used in the // many useful constants and utility routines that are used in the
// implementation of the soft-float routines in compiler-rt. // implementation of the soft-float routines in compiler-rt.
// //
// Assumes that float and double correspond to the IEEE-754 binary32 and // Assumes that float, double and long double correspond to the IEEE-754
// binary64 types, respectively, and that integer endianness matches floating // binary32, binary64 and binary 128 types, respectively, and that integer
// point endianness on the target platform. // endianness matches floating point endianness on the target platform.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef FP_LIB_HEADER #ifndef FP_LIB_HEADER
#define FP_LIB_HEADER #define FP_LIB_HEADER
#include <stdint.h> #include "int_lib.h"
#include "int_math.h"
#include <limits.h> #include <limits.h>
#include <stdbool.h>
#include <stdint.h>
typedef unsigned long long uint64_t; // x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in
// 32-bit mode.
#define UINT32_C(x) (x##U) #if defined(__FreeBSD__) && defined(__i386__)
#include <sys/param.h>
#if __FreeBSD_version < 903000 // v9.3
#define uint64_t unsigned long long
#define int64_t long long
#undef UINT64_C
#define UINT64_C(c) (c##ULL)
#endif
#endif
#if defined SINGLE_PRECISION #if defined SINGLE_PRECISION
typedef uint16_t half_rep_t;
typedef uint32_t rep_t; typedef uint32_t rep_t;
typedef uint64_t twice_rep_t;
typedef int32_t srep_t; typedef int32_t srep_t;
typedef float fp_t; typedef float fp_t;
#define HALF_REP_C UINT16_C
#define REP_C UINT32_C #define REP_C UINT32_C
#define significandBits 23 #define significandBits 23
static inline int rep_clz(rep_t a) static __inline int rep_clz(rep_t a) { return clzsi(a); }
{
return __builtin_clz(a);
}
// 32x32 --> 64 bit multiply // 32x32 --> 64 bit multiply
static inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
{ const uint64_t product = (uint64_t)a * b;
const uint64_t product = (uint64_t)a*b; *hi = product >> 32;
*hi = product >> 32; *lo = product;
*lo = product;
} }
COMPILER_RT_ABI fp_t __addsf3(fp_t a, fp_t b);
#elif defined DOUBLE_PRECISION #elif defined DOUBLE_PRECISION
typedef uint32_t half_rep_t;
typedef uint64_t rep_t; typedef uint64_t rep_t;
typedef int64_t srep_t; typedef int64_t srep_t;
typedef double fp_t; typedef double fp_t;
#define HALF_REP_C UINT32_C
#define REP_C UINT64_C #define REP_C UINT64_C
#define significandBits 52 #define significandBits 52
static inline int rep_clz(rep_t a) static __inline int rep_clz(rep_t a) {
{
#if defined __LP64__ #if defined __LP64__
return __builtin_clzl(a); return __builtin_clzl(a);
#else #else
if (a & REP_C(0xffffffff00000000)) if (a & REP_C(0xffffffff00000000))
return __builtin_clz(a >> 32); return clzsi(a >> 32);
else else
return 32 + __builtin_clz(a & REP_C(0xffffffff)); return 32 + clzsi(a & REP_C(0xffffffff));
#endif #endif
} }
@@ -75,81 +86,241 @@ static inline int rep_clz(rep_t a)
// 64x64 -> 128 wide multiply for platforms that don't have such an operation; // 64x64 -> 128 wide multiply for platforms that don't have such an operation;
// many 64-bit platforms have this operation, but they tend to have hardware // many 64-bit platforms have this operation, but they tend to have hardware
// floating-point, so we don't bother with a special case for them here. // floating-point, so we don't bother with a special case for them here.
static inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
{ // Each of the component 32x32 -> 64 products
// Each of the component 32x32 -> 64 products const uint64_t plolo = loWord(a) * loWord(b);
const uint64_t plolo = loWord(a) * loWord(b); const uint64_t plohi = loWord(a) * hiWord(b);
const uint64_t plohi = loWord(a) * hiWord(b); const uint64_t philo = hiWord(a) * loWord(b);
const uint64_t philo = hiWord(a) * loWord(b); const uint64_t phihi = hiWord(a) * hiWord(b);
const uint64_t phihi = hiWord(a) * hiWord(b); // Sum terms that contribute to lo in a way that allows us to get the carry
// Sum terms that contribute to lo in a way that allows us to get the carry const uint64_t r0 = loWord(plolo);
const uint64_t r0 = loWord(plolo); const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo);
const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo); *lo = r0 + (r1 << 32);
*lo = r0 + (r1 << 32); // Sum terms contributing to hi with the carry from lo
// Sum terms contributing to hi with the carry from lo *hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi;
*hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi; }
#undef loWord
#undef hiWord
COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b);
#elif defined QUAD_PRECISION
#if __LDBL_MANT_DIG__ == 113 && defined(__SIZEOF_INT128__)
#define CRT_LDBL_128BIT
typedef uint64_t half_rep_t;
typedef __uint128_t rep_t;
typedef __int128_t srep_t;
typedef long double fp_t;
#define HALF_REP_C UINT64_C
#define REP_C (__uint128_t)
// Note: Since there is no explicit way to tell compiler the constant is a
// 128-bit integer, we let the constant be casted to 128-bit integer
#define significandBits 112
static __inline int rep_clz(rep_t a) {
const union {
__uint128_t ll;
#if _YUGA_BIG_ENDIAN
struct {
uint64_t high, low;
} s;
#else
struct {
uint64_t low, high;
} s;
#endif
} uu = {.ll = a};
uint64_t word;
uint64_t add;
if (uu.s.high) {
word = uu.s.high;
add = 0;
} else {
word = uu.s.low;
add = 64;
}
return __builtin_clzll(word) + add;
} }
#define Word_LoMask UINT64_C(0x00000000ffffffff)
#define Word_HiMask UINT64_C(0xffffffff00000000)
#define Word_FullMask UINT64_C(0xffffffffffffffff)
#define Word_1(a) (uint64_t)((a >> 96) & Word_LoMask)
#define Word_2(a) (uint64_t)((a >> 64) & Word_LoMask)
#define Word_3(a) (uint64_t)((a >> 32) & Word_LoMask)
#define Word_4(a) (uint64_t)(a & Word_LoMask)
// 128x128 -> 256 wide multiply for platforms that don't have such an operation;
// many 64-bit platforms have this operation, but they tend to have hardware
// floating-point, so we don't bother with a special case for them here.
static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
const uint64_t product11 = Word_1(a) * Word_1(b);
const uint64_t product12 = Word_1(a) * Word_2(b);
const uint64_t product13 = Word_1(a) * Word_3(b);
const uint64_t product14 = Word_1(a) * Word_4(b);
const uint64_t product21 = Word_2(a) * Word_1(b);
const uint64_t product22 = Word_2(a) * Word_2(b);
const uint64_t product23 = Word_2(a) * Word_3(b);
const uint64_t product24 = Word_2(a) * Word_4(b);
const uint64_t product31 = Word_3(a) * Word_1(b);
const uint64_t product32 = Word_3(a) * Word_2(b);
const uint64_t product33 = Word_3(a) * Word_3(b);
const uint64_t product34 = Word_3(a) * Word_4(b);
const uint64_t product41 = Word_4(a) * Word_1(b);
const uint64_t product42 = Word_4(a) * Word_2(b);
const uint64_t product43 = Word_4(a) * Word_3(b);
const uint64_t product44 = Word_4(a) * Word_4(b);
const __uint128_t sum0 = (__uint128_t)product44;
const __uint128_t sum1 = (__uint128_t)product34 + (__uint128_t)product43;
const __uint128_t sum2 =
(__uint128_t)product24 + (__uint128_t)product33 + (__uint128_t)product42;
const __uint128_t sum3 = (__uint128_t)product14 + (__uint128_t)product23 +
(__uint128_t)product32 + (__uint128_t)product41;
const __uint128_t sum4 =
(__uint128_t)product13 + (__uint128_t)product22 + (__uint128_t)product31;
const __uint128_t sum5 = (__uint128_t)product12 + (__uint128_t)product21;
const __uint128_t sum6 = (__uint128_t)product11;
const __uint128_t r0 = (sum0 & Word_FullMask) + ((sum1 & Word_LoMask) << 32);
const __uint128_t r1 = (sum0 >> 64) + ((sum1 >> 32) & Word_FullMask) +
(sum2 & Word_FullMask) + ((sum3 << 32) & Word_HiMask);
*lo = r0 + (r1 << 64);
*hi = (r1 >> 64) + (sum1 >> 96) + (sum2 >> 64) + (sum3 >> 32) + sum4 +
(sum5 << 32) + (sum6 << 64);
}
#undef Word_1
#undef Word_2
#undef Word_3
#undef Word_4
#undef Word_HiMask
#undef Word_LoMask
#undef Word_FullMask
#endif // __LDBL_MANT_DIG__ == 113 && __SIZEOF_INT128__
#else #else
#error Either SINGLE_PRECISION or DOUBLE_PRECISION must be defined. #error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined.
#endif #endif
#define typeWidth (sizeof(rep_t)*CHAR_BIT) #if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || \
#define exponentBits (typeWidth - significandBits - 1) defined(CRT_LDBL_128BIT)
#define maxExponent ((1 << exponentBits) - 1) #define typeWidth (sizeof(rep_t) * CHAR_BIT)
#define exponentBias (maxExponent >> 1) #define exponentBits (typeWidth - significandBits - 1)
#define maxExponent ((1 << exponentBits) - 1)
#define exponentBias (maxExponent >> 1)
#define implicitBit (REP_C(1) << significandBits) #define implicitBit (REP_C(1) << significandBits)
#define significandMask (implicitBit - 1U) #define significandMask (implicitBit - 1U)
#define signBit (REP_C(1) << (significandBits + exponentBits)) #define signBit (REP_C(1) << (significandBits + exponentBits))
#define absMask (signBit - 1U) #define absMask (signBit - 1U)
#define exponentMask (absMask ^ significandMask) #define exponentMask (absMask ^ significandMask)
#define oneRep ((rep_t)exponentBias << significandBits) #define oneRep ((rep_t)exponentBias << significandBits)
#define infRep exponentMask #define infRep exponentMask
#define quietBit (implicitBit >> 1) #define quietBit (implicitBit >> 1)
#define qnanRep (exponentMask | quietBit) #define qnanRep (exponentMask | quietBit)
static inline rep_t toRep(fp_t x) static __inline rep_t toRep(fp_t x) {
{ const union {
const union { fp_t f; rep_t i; } rep = {.f = x}; fp_t f;
return rep.i; rep_t i;
} rep = {.f = x};
return rep.i;
} }
static inline fp_t fromRep(rep_t x) static __inline fp_t fromRep(rep_t x) {
{ const union {
const union { fp_t f; rep_t i; } rep = {.i = x}; fp_t f;
return rep.f; rep_t i;
} rep = {.i = x};
return rep.f;
} }
static inline int normalize(rep_t *significand) static __inline int normalize(rep_t *significand) {
{ const int shift = rep_clz(*significand) - rep_clz(implicitBit);
const int shift = rep_clz(*significand) - rep_clz(implicitBit); *significand <<= shift;
*significand <<= shift; return 1 - shift;
return 1 - shift;
} }
static inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) static __inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) {
{ *hi = *hi << count | *lo >> (typeWidth - count);
*hi = *hi << count | *lo >> (typeWidth - count); *lo = *lo << count;
*lo = *lo << count;
} }
static inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned int count) static __inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo,
{ unsigned int count) {
if (count < typeWidth) { if (count < typeWidth) {
int sticky = (*lo << (typeWidth - count)) != 0; const bool sticky = (*lo << (typeWidth - count)) != 0;
*lo = *hi << (typeWidth - count) | *lo >> count | sticky; *lo = *hi << (typeWidth - count) | *lo >> count | sticky;
*hi = *hi >> count; *hi = *hi >> count;
} } else if (count < 2 * typeWidth) {
else if (count < 2*typeWidth) { const bool sticky = *hi << (2 * typeWidth - count) | *lo;
int sticky = (*hi << (2*typeWidth - count) | *lo) != 0; *lo = *hi >> (count - typeWidth) | sticky;
*lo = *hi >> (count - typeWidth) | sticky; *hi = 0;
*hi = 0; } else {
const bool sticky = *hi | *lo;
*lo = sticky;
*hi = 0;
}
}
// Implements logb methods (logb, logbf, logbl) for IEEE-754. This avoids
// pulling in a libm dependency from compiler-rt, but is not meant to replace
// it (i.e. code calling logb() should get the one from libm, not this), hence
// the __compiler_rt prefix.
static __inline fp_t __compiler_rt_logbX(fp_t x) {
rep_t rep = toRep(x);
int exp = (rep & exponentMask) >> significandBits;
// Abnormal cases:
// 1) +/- inf returns +inf; NaN returns NaN
// 2) 0.0 returns -inf
if (exp == maxExponent) {
if (((rep & signBit) == 0) || (x != x)) {
return x; // NaN or +inf: return x
} else { } else {
int sticky = (*hi | *lo) != 0; return -x; // -inf: return -x
*lo = sticky;
*hi = 0;
} }
} else if (x == 0.0) {
// 0.0: return -inf
return fromRep(infRep | signBit);
}
if (exp != 0) {
// Normal number
return exp - exponentBias; // Unbias exponent
} else {
// Subnormal number; normalize and repeat
rep &= absMask;
const int shift = 1 - normalize(&rep);
exp = (rep & exponentMask) >> significandBits;
return exp - exponentBias - shift; // Unbias exponent
}
} }
#endif
#if defined(SINGLE_PRECISION)
static __inline fp_t __compiler_rt_logbf(fp_t x) {
return __compiler_rt_logbX(x);
}
#elif defined(DOUBLE_PRECISION)
static __inline fp_t __compiler_rt_logb(fp_t x) {
return __compiler_rt_logbX(x);
}
#elif defined(QUAD_PRECISION)
#if defined(CRT_LDBL_128BIT)
static __inline fp_t __compiler_rt_logbl(fp_t x) {
return __compiler_rt_logbX(x);
}
#else
// The generic implementation only works for ieee754 floating point. For other
// floating point types, continue to rely on the libm implementation for now.
static __inline long double __compiler_rt_logbl(long double x) {
return crt_logbl(x);
}
#endif
#endif
#endif // FP_LIB_HEADER #endif // FP_LIB_HEADER

View File

@@ -1,9 +1,8 @@
//===-- lib/mulsf3.c - Single-precision multiplication ------------*- C -*-===// //===-- lib/mulsf3.c - Single-precision multiplication ------------*- C -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Source Licenses. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
@@ -13,98 +12,14 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define SINGLE_PRECISION #define SINGLE_PRECISION
#include "fp_lib.h" #include "fp_mul_impl.inc"
fp_t COMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) { return __mulXf3__(a, b); }
__mulsf3(fp_t a, fp_t b)
{
const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit;
rep_t aSignificand = toRep(a) & significandMask; #if defined(__ARM_EABI__)
rep_t bSignificand = toRep(b) & significandMask; #if defined(COMPILER_RT_ARMHF_TARGET)
int scale = 0; AEABI_RTABI fp_t __aeabi_fmul(fp_t a, fp_t b) { return __mulsf3(a, b); }
#else
// Detect if a or b is zero, denormal, infinity, or NaN. COMPILER_RT_ALIAS(__mulsf3, __aeabi_fmul)
if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { #endif
#endif
const rep_t aAbs = toRep(a) & absMask;
const rep_t bAbs = toRep(b) & absMask;
// NaN * anything = qNaN
if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
// anything * NaN = qNaN
if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
if (aAbs == infRep) {
// infinity * non-zero = +/- infinity
if (bAbs) return fromRep(aAbs | productSign);
// infinity * zero = NaN
else return fromRep(qnanRep);
}
if (bAbs == infRep) {
// non-zero * infinity = +/- infinity
if (aAbs) return fromRep(bAbs | productSign);
// zero * infinity = NaN
else return fromRep(qnanRep);
}
// zero * anything = +/- zero
if (!aAbs) return fromRep(productSign);
// anything * zero = +/- zero
if (!bAbs) return fromRep(productSign);
// one or both of a or b is denormal, the other (if applicable) is a
// normal number. Renormalize one or both of a and b, and set scale to
// include the necessary exponent adjustment.
if (aAbs < implicitBit) scale += normalize(&aSignificand);
if (bAbs < implicitBit) scale += normalize(&bSignificand);
}
// Or in the implicit significand bit. (If we fell through from the
// denormal path it was already set by normalize( ), but setting it twice
// won't hurt anything.)
aSignificand |= implicitBit;
bSignificand |= implicitBit;
// Get the significand of a*b. Before multiplying the significands, shift
// one of them left to left-align it in the field. Thus, the product will
// have (exponentBits + 2) integral digits, all but two of which must be
// zero. Normalizing this result is just a conditional left-shift by one
// and bumping the exponent accordingly.
rep_t productHi, productLo;
wideMultiply(aSignificand, bSignificand << exponentBits,
&productHi, &productLo);
int productExponent = aExponent + bExponent - exponentBias + scale;
// Normalize the significand, adjust exponent if needed.
if (productHi & implicitBit) productExponent++;
else wideLeftShift(&productHi, &productLo, 1);
// If we have overflowed the type, return +/- infinity.
if (productExponent >= maxExponent) return fromRep(infRep | productSign);
if (productExponent <= 0) {
// Result is denormal before rounding, the exponent is zero and we
// need to shift the significand.
wideRightShiftWithSticky(&productHi, &productLo, 1U - (unsigned)productExponent);
}
else {
// Result is normal before rounding; insert the exponent.
productHi &= significandMask;
productHi |= (rep_t)productExponent << significandBits;
}
// Insert the sign of the result:
productHi |= productSign;
// Final rounding. The final result may overflow to infinity, or underflow
// to zero, but those are the correct results in those cases.
if (productLo > signBit) productHi++;
if (productLo == signBit) productHi += productHi & 1;
return fromRep(productHi);
}

View File

@@ -1,21 +0,0 @@
//===-- lib/negsf2.c - single-precision negation ------------------*- 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 soft-float negation.
//
//===----------------------------------------------------------------------===//
#define SINGLE_PRECISION
#include "fp_lib.h"
fp_t
__negsf2(fp_t a)
{
return fromRep(toRep(a) ^ signBit);
}

View File

@@ -1,25 +1,27 @@
//===-- lib/subsf3.c - Single-precision subtraction ---------------*- C -*-===// //===-- lib/subsf3.c - Single-precision subtraction ---------------*- C -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is dual licensed under the MIT and the University of Illinois Open // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Source Licenses. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file implements single-precision soft-float subtraction with the // This file implements single-precision soft-float subtraction.
// IEEE-754 default rounding (to nearest, ties to even).
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define SINGLE_PRECISION #define SINGLE_PRECISION
#include "fp_lib.h" #include "fp_lib.h"
fp_t __addsf3(fp_t a, fp_t b);
// Subtraction; flip the sign bit of b and add. // Subtraction; flip the sign bit of b and add.
fp_t COMPILER_RT_ABI fp_t __subsf3(fp_t a, fp_t b) {
__subsf3(fp_t a, fp_t b) return __addsf3(a, fromRep(toRep(b) ^ signBit));
{
return __addsf3(a, fromRep(toRep(b) ^ signBit));
} }
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_fsub(fp_t a, fp_t b) { return __subsf3(a, b); }
#else
COMPILER_RT_ALIAS(__subsf3, __aeabi_fsub)
#endif
#endif

View File

@@ -1,37 +0,0 @@
TOPSRC = $(shell cd ../..; pwd)
include $(TOPSRC)/target.mk
CFLAGS += ${DEFS} -Werror -Wall
OBJS = adddf3.o \
addsf3.o \
divdf3.o \
divsf3.o \
comparedf2.o \
comparesf2.o \
extendsfdf2.o \
fixdfsi.o \
fixsfsi.o \
floatsidf.o \
floatsisf.o \
floatunsisf.o \
fp_mode.o \
muldf3.o \
mulsf3.o \
subdf3.o \
subsf3.o \
truncdfsf2.o
all: ../libclang.a
../libclang.a: ${OBJS}
$(AR) cru $@ ${OBJS}
$(RANLIB) $@
install: all
# ${INSTALLDIR} ${DESTDIR}/lib
# ${INSTALL} ../libclang.a ${DESTDIR}/lib/libclang.a
# $(RANLIB) ${DESTDIR}/lib/libclang.a
clean:
rm -f ../libclang.a *.o *~ tags

View File

@@ -1,353 +0,0 @@
Compiler-RT
================================
This directory and its subdirectories contain source code for the compiler
support routines.
Compiler-RT is open source software. You may freely distribute it under the
terms of the license agreement found in LICENSE.txt.
================================
This is a replacement library for libgcc. Each function is contained
in its own file. Each function has a corresponding unit test under
test/Unit.
A rudimentary script to test each file is in the file called
test/Unit/test.
Here is the specification for this library:
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc
Please note that the libgcc specification explicitly mentions actual types of
arguments and returned values being expressed with machine modes.
In some cases particular types such as "int", "unsigned", "long long", etc.
may be specified just as examples there.
Here is a synopsis of the contents of this library:
typedef int32_t si_int;
typedef uint32_t su_int;
typedef int64_t di_int;
typedef uint64_t du_int;
// Integral bit manipulation
di_int __ashldi3(di_int a, si_int b); // a << b
ti_int __ashlti3(ti_int a, si_int b); // a << b
di_int __ashrdi3(di_int a, si_int b); // a >> b arithmetic (sign fill)
ti_int __ashrti3(ti_int a, si_int b); // a >> b arithmetic (sign fill)
di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill)
ti_int __lshrti3(ti_int a, si_int b); // a >> b logical (zero fill)
int __clzsi2(si_int a); // count leading zeros
int __clzdi2(di_int a); // count leading zeros
int __clzti2(ti_int a); // count leading zeros
int __ctzsi2(si_int a); // count trailing zeros
int __ctzdi2(di_int a); // count trailing zeros
int __ctzti2(ti_int a); // count trailing zeros
int __ffssi2(si_int a); // find least significant 1 bit
int __ffsdi2(di_int a); // find least significant 1 bit
int __ffsti2(ti_int a); // find least significant 1 bit
int __paritysi2(si_int a); // bit parity
int __paritydi2(di_int a); // bit parity
int __parityti2(ti_int a); // bit parity
int __popcountsi2(si_int a); // bit population
int __popcountdi2(di_int a); // bit population
int __popcountti2(ti_int a); // bit population
uint32_t __bswapsi2(uint32_t a); // a byteswapped
uint64_t __bswapdi2(uint64_t a); // a byteswapped
// Integral arithmetic
di_int __negdi2 (di_int a); // -a
ti_int __negti2 (ti_int a); // -a
di_int __muldi3 (di_int a, di_int b); // a * b
ti_int __multi3 (ti_int a, ti_int b); // a * b
si_int __divsi3 (si_int a, si_int b); // a / b signed
di_int __divdi3 (di_int a, di_int b); // a / b signed
ti_int __divti3 (ti_int a, ti_int b); // a / b signed
su_int __udivsi3 (su_int n, su_int d); // a / b unsigned
du_int __udivdi3 (du_int a, du_int b); // a / b unsigned
tu_int __udivti3 (tu_int a, tu_int b); // a / b unsigned
si_int __modsi3 (si_int a, si_int b); // a % b signed
di_int __moddi3 (di_int a, di_int b); // a % b signed
ti_int __modti3 (ti_int a, ti_int b); // a % b signed
su_int __umodsi3 (su_int a, su_int b); // a % b unsigned
du_int __umoddi3 (du_int a, du_int b); // a % b unsigned
tu_int __umodti3 (tu_int a, tu_int b); // a % b unsigned
du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b unsigned
tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); // a / b, *rem = a % b unsigned
su_int __udivmodsi4(su_int a, su_int b, su_int* rem); // a / b, *rem = a % b unsigned
si_int __divmodsi4(si_int a, si_int b, si_int* rem); // a / b, *rem = a % b signed
di_int __divmoddi4(di_int a, di_int b, di_int* rem); // a / b, *rem = a % b signed
ti_int __divmodti4(ti_int a, ti_int b, ti_int* rem); // a / b, *rem = a % b signed
// Integral arithmetic with trapping overflow
si_int __absvsi2(si_int a); // abs(a)
di_int __absvdi2(di_int a); // abs(a)
ti_int __absvti2(ti_int a); // abs(a)
si_int __negvsi2(si_int a); // -a
di_int __negvdi2(di_int a); // -a
ti_int __negvti2(ti_int a); // -a
si_int __addvsi3(si_int a, si_int b); // a + b
di_int __addvdi3(di_int a, di_int b); // a + b
ti_int __addvti3(ti_int a, ti_int b); // a + b
si_int __subvsi3(si_int a, si_int b); // a - b
di_int __subvdi3(di_int a, di_int b); // a - b
ti_int __subvti3(ti_int a, ti_int b); // a - b
si_int __mulvsi3(si_int a, si_int b); // a * b
di_int __mulvdi3(di_int a, di_int b); // a * b
ti_int __mulvti3(ti_int a, ti_int b); // a * b
// Integral arithmetic which returns if overflow
si_int __mulosi4(si_int a, si_int b, int* overflow); // a * b, overflow set to one if result not in signed range
di_int __mulodi4(di_int a, di_int b, int* overflow); // a * b, overflow set to one if result not in signed range
ti_int __muloti4(ti_int a, ti_int b, int* overflow); // a * b, overflow set to
one if result not in signed range
// Integral comparison: a < b -> 0
// a == b -> 1
// a > b -> 2
si_int __cmpdi2 (di_int a, di_int b);
si_int __cmpti2 (ti_int a, ti_int b);
si_int __ucmpdi2(du_int a, du_int b);
si_int __ucmpti2(tu_int a, tu_int b);
// Integral / floating point conversion
di_int __fixsfdi( float a);
di_int __fixdfdi( double a);
di_int __fixxfdi(long double a);
ti_int __fixsfti( float a);
ti_int __fixdfti( double a);
ti_int __fixxfti(long double a);
uint64_t __fixtfdi(long double input); // ppc only, doesn't match documentation
su_int __fixunssfsi( float a);
su_int __fixunsdfsi( double a);
su_int __fixunsxfsi(long double a);
du_int __fixunssfdi( float a);
du_int __fixunsdfdi( double a);
du_int __fixunsxfdi(long double a);
tu_int __fixunssfti( float a);
tu_int __fixunsdfti( double a);
tu_int __fixunsxfti(long double a);
uint64_t __fixunstfdi(long double input); // ppc only
float __floatdisf(di_int a);
double __floatdidf(di_int a);
long double __floatdixf(di_int a);
long double __floatditf(int64_t a); // ppc only
float __floattisf(ti_int a);
double __floattidf(ti_int a);
long double __floattixf(ti_int a);
float __floatundisf(du_int a);
double __floatundidf(du_int a);
long double __floatundixf(du_int a);
long double __floatunditf(uint64_t a); // ppc only
float __floatuntisf(tu_int a);
double __floatuntidf(tu_int a);
long double __floatuntixf(tu_int a);
// Floating point raised to integer power
float __powisf2( float a, int b); // a ^ b
double __powidf2( double a, int b); // a ^ b
long double __powixf2(long double a, int b); // a ^ b
long double __powitf2(long double a, int b); // ppc only, a ^ b
// Complex arithmetic
// (a + ib) * (c + id)
float _Complex __mulsc3( float a, float b, float c, float d);
double _Complex __muldc3(double a, double b, double c, double d);
long double _Complex __mulxc3(long double a, long double b,
long double c, long double d);
long double _Complex __multc3(long double a, long double b,
long double c, long double d); // ppc only
// (a + ib) / (c + id)
float _Complex __divsc3( float a, float b, float c, float d);
double _Complex __divdc3(double a, double b, double c, double d);
long double _Complex __divxc3(long double a, long double b,
long double c, long double d);
long double _Complex __divtc3(long double a, long double b,
long double c, long double d); // ppc only
// Runtime support
// __clear_cache() is used to tell process that new instructions have been
// written to an address range. Necessary on processors that do not have
// a unified instruction and data cache.
void __clear_cache(void* start, void* end);
// __enable_execute_stack() is used with nested functions when a trampoline
// function is written onto the stack and that page range needs to be made
// executable.
void __enable_execute_stack(void* addr);
// __gcc_personality_v0() is normally only called by the system unwinder.
// C code (as opposed to C++) normally does not need a personality function
// because there are no catch clauses or destructors to be run. But there
// is a C language extension __attribute__((cleanup(func))) which marks local
// variables as needing the cleanup function "func" to be run when the
// variable goes out of scope. That includes when an exception is thrown,
// so a personality handler is needed.
_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,
uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
_Unwind_Context_t context);
// for use with some implementations of assert() in <assert.h>
void __eprintf(const char* format, const char* assertion_expression,
const char* line, const char* file);
// for systems with emulated thread local storage
void* __emutls_get_address(struct __emutls_control*);
// Power PC specific functions
// There is no C interface to the saveFP/restFP functions. They are helper
// functions called by the prolog and epilog of functions that need to save
// a number of non-volatile float point registers.
saveFP
restFP
// PowerPC has a standard template for trampoline functions. This function
// generates a custom trampoline function with the specific realFunc
// and localsPtr values.
void __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated,
const void* realFunc, void* localsPtr);
// adds two 128-bit double-double precision values ( x + y )
long double __gcc_qadd(long double x, long double y);
// subtracts two 128-bit double-double precision values ( x - y )
long double __gcc_qsub(long double x, long double y);
// multiples two 128-bit double-double precision values ( x * y )
long double __gcc_qmul(long double x, long double y);
// divides two 128-bit double-double precision values ( x / y )
long double __gcc_qdiv(long double a, long double b);
// ARM specific functions
// There is no C interface to the switch* functions. These helper functions
// are only needed by Thumb1 code for efficient switch table generation.
switch16
switch32
switch8
switchu8
// There is no C interface to the *_vfp_d8_d15_regs functions. There are
// called in the prolog and epilog of Thumb1 functions. When the C++ ABI use
// SJLJ for exceptions, each function with a catch clause or destuctors needs
// to save and restore all registers in it prolog and epliog. But there is
// no way to access vector and high float registers from thumb1 code, so the
// compiler must add call outs to these helper functions in the prolog and
// epilog.
restore_vfp_d8_d15_regs
save_vfp_d8_d15_regs
// Note: long ago ARM processors did not have floating point hardware support.
// Floating point was done in software and floating point parameters were
// passed in integer registers. When hardware support was added for floating
// point, new *vfp functions were added to do the same operations but with
// floating point parameters in floating point registers.
// Undocumented functions
float __addsf3vfp(float a, float b); // Appears to return a + b
double __adddf3vfp(double a, double b); // Appears to return a + b
float __divsf3vfp(float a, float b); // Appears to return a / b
double __divdf3vfp(double a, double b); // Appears to return a / b
int __eqsf2vfp(float a, float b); // Appears to return one
// iff a == b and neither is NaN.
int __eqdf2vfp(double a, double b); // Appears to return one
// iff a == b and neither is NaN.
double __extendsfdf2vfp(float a); // Appears to convert from
// float to double.
int __fixdfsivfp(double a); // Appears to convert from
// double to int.
int __fixsfsivfp(float a); // Appears to convert from
// float to int.
unsigned int __fixunssfsivfp(float a); // Appears to convert from
// float to unsigned int.
unsigned int __fixunsdfsivfp(double a); // Appears to convert from
// double to unsigned int.
double __floatsidfvfp(int a); // Appears to convert from
// int to double.
float __floatsisfvfp(int a); // Appears to convert from
// int to float.
double __floatunssidfvfp(unsigned int a); // Appears to convert from
// unisgned int to double.
float __floatunssisfvfp(unsigned int a); // Appears to convert from
// unisgned int to float.
int __gedf2vfp(double a, double b); // Appears to return __gedf2
// (a >= b)
int __gesf2vfp(float a, float b); // Appears to return __gesf2
// (a >= b)
int __gtdf2vfp(double a, double b); // Appears to return __gtdf2
// (a > b)
int __gtsf2vfp(float a, float b); // Appears to return __gtsf2
// (a > b)
int __ledf2vfp(double a, double b); // Appears to return __ledf2
// (a <= b)
int __lesf2vfp(float a, float b); // Appears to return __lesf2
// (a <= b)
int __ltdf2vfp(double a, double b); // Appears to return __ltdf2
// (a < b)
int __ltsf2vfp(float a, float b); // Appears to return __ltsf2
// (a < b)
double __muldf3vfp(double a, double b); // Appears to return a * b
float __mulsf3vfp(float a, float b); // Appears to return a * b
int __nedf2vfp(double a, double b); // Appears to return __nedf2
// (a != b)
double __negdf2vfp(double a); // Appears to return -a
float __negsf2vfp(float a); // Appears to return -a
float __negsf2vfp(float a); // Appears to return -a
double __subdf3vfp(double a, double b); // Appears to return a - b
float __subsf3vfp(float a, float b); // Appears to return a - b
float __truncdfsf2vfp(double a); // Appears to convert from
// double to float.
int __unorddf2vfp(double a, double b); // Appears to return __unorddf2
int __unordsf2vfp(float a, float b); // Appears to return __unordsf2
Preconditions are listed for each function at the definition when there are any.
Any preconditions reflect the specification at
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc.
Assumptions are listed in "int_lib.h", and in individual files. Where possible
assumptions are checked at compile time.

View File

@@ -1,24 +0,0 @@
//===-- lib/addsf3.c - Single-precision addition ------------------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements single-precision soft-float addition.
//
//===----------------------------------------------------------------------===//
#define SINGLE_PRECISION
#include "fp_add_impl.inc"
COMPILER_RT_ABI float __addsf3(float a, float b) { return __addXf3__(a, b); }
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI float __aeabi_fadd(float a, float b) { return __addsf3(a, b); }
#else
COMPILER_RT_ALIAS(__addsf3, __aeabi_fadd)
#endif
#endif

View File

@@ -1,151 +0,0 @@
//===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the following soft-fp_t comparison routines:
//
// __eqsf2 __gesf2 __unordsf2
// __lesf2 __gtsf2
// __ltsf2
// __nesf2
//
// The semantics of the routines grouped in each column are identical, so there
// is a single implementation for each, and wrappers to provide the other names.
//
// The main routines behave as follows:
//
// __lesf2(a,b) returns -1 if a < b
// 0 if a == b
// 1 if a > b
// 1 if either a or b is NaN
//
// __gesf2(a,b) returns -1 if a < b
// 0 if a == b
// 1 if a > b
// -1 if either a or b is NaN
//
// __unordsf2(a,b) returns 0 if both a and b are numbers
// 1 if either a or b is NaN
//
// Note that __lesf2( ) and __gesf2( ) are identical except in their handling of
// NaN values.
//
//===----------------------------------------------------------------------===//
#define SINGLE_PRECISION
#include "fp_lib.h"
enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 };
COMPILER_RT_ABI enum LE_RESULT __lesf2(fp_t a, fp_t b) {
const srep_t aInt = toRep(a);
const srep_t bInt = toRep(b);
const rep_t aAbs = aInt & absMask;
const rep_t bAbs = bInt & absMask;
// If either a or b is NaN, they are unordered.
if (aAbs > infRep || bAbs > infRep)
return LE_UNORDERED;
// If a and b are both zeros, they are equal.
if ((aAbs | bAbs) == 0)
return LE_EQUAL;
// If at least one of a and b is positive, we get the same result comparing
// a and b as signed integers as we would with a fp_ting-point compare.
if ((aInt & bInt) >= 0) {
if (aInt < bInt)
return LE_LESS;
else if (aInt == bInt)
return LE_EQUAL;
else
return LE_GREATER;
}
// Otherwise, both are negative, so we need to flip the sense of the
// comparison to get the correct result. (This assumes a twos- or ones-
// complement integer representation; if integers are represented in a
// sign-magnitude representation, then this flip is incorrect).
else {
if (aInt > bInt)
return LE_LESS;
else if (aInt == bInt)
return LE_EQUAL;
else
return LE_GREATER;
}
}
#if defined(__ELF__)
// Alias for libgcc compatibility
COMPILER_RT_ALIAS(__lesf2, __cmpsf2)
#endif
COMPILER_RT_ALIAS(__lesf2, __eqsf2)
COMPILER_RT_ALIAS(__lesf2, __ltsf2)
COMPILER_RT_ALIAS(__lesf2, __nesf2)
enum GE_RESULT {
GE_LESS = -1,
GE_EQUAL = 0,
GE_GREATER = 1,
GE_UNORDERED = -1 // Note: different from LE_UNORDERED
};
COMPILER_RT_ABI enum GE_RESULT __gesf2(fp_t a, fp_t b) {
const srep_t aInt = toRep(a);
const srep_t bInt = toRep(b);
const rep_t aAbs = aInt & absMask;
const rep_t bAbs = bInt & absMask;
if (aAbs > infRep || bAbs > infRep)
return GE_UNORDERED;
if ((aAbs | bAbs) == 0)
return GE_EQUAL;
if ((aInt & bInt) >= 0) {
if (aInt < bInt)
return GE_LESS;
else if (aInt == bInt)
return GE_EQUAL;
else
return GE_GREATER;
} else {
if (aInt > bInt)
return GE_LESS;
else if (aInt == bInt)
return GE_EQUAL;
else
return GE_GREATER;
}
}
COMPILER_RT_ALIAS(__gesf2, __gtsf2)
COMPILER_RT_ABI int
__unordsf2(fp_t a, fp_t b) {
const rep_t aAbs = toRep(a) & absMask;
const rep_t bAbs = toRep(b) & absMask;
return aAbs > infRep || bAbs > infRep;
}
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI int __aeabi_fcmpun(fp_t a, fp_t b) { return __unordsf2(a, b); }
#else
COMPILER_RT_ALIAS(__unordsf2, __aeabi_fcmpun)
#endif
#endif
#if defined(_WIN32) && !defined(__MINGW32__)
// The alias mechanism doesn't work on Windows except for MinGW, so emit
// wrapper functions.
int __eqsf2(fp_t a, fp_t b) { return __lesf2(a, b); }
int __ltsf2(fp_t a, fp_t b) { return __lesf2(a, b); }
int __nesf2(fp_t a, fp_t b) { return __lesf2(a, b); }
int __gtsf2(fp_t a, fp_t b) { return __gesf2(a, b); }
#endif

View File

@@ -1,30 +0,0 @@
//===-- lib/divsf3.c - Single-precision division ------------------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements single-precision soft-float division
// with the IEEE-754 default rounding (to nearest, ties to even).
//
//===----------------------------------------------------------------------===//
#define SINGLE_PRECISION
#define NUMBER_OF_HALF_ITERATIONS 0
#define NUMBER_OF_FULL_ITERATIONS 3
#define USE_NATIVE_FULL_ITERATIONS
#include "fp_div_impl.inc"
COMPILER_RT_ABI fp_t __divsf3(fp_t a, fp_t b) { return __divXf3__(a, b); }
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_fdiv(fp_t a, fp_t b) { return __divsf3(a, b); }
#else
COMPILER_RT_ALIAS(__divsf3, __aeabi_fdiv)
#endif
#endif

View File

@@ -1,23 +0,0 @@
//===-- fixsfsi.c - Implement __fixsfsi -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#define SINGLE_PRECISION
#include "fp_lib.h"
typedef si_int fixint_t;
typedef su_int fixuint_t;
#include "fp_fixint_impl.inc"
COMPILER_RT_ABI si_int __fixsfsi(fp_t a) { return __fixint(a); }
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI si_int __aeabi_f2iz(fp_t a) { return __fixsfsi(a); }
#else
COMPILER_RT_ALIAS(__fixsfsi, __aeabi_f2iz)
#endif
#endif

View File

@@ -1,65 +0,0 @@
//===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements 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"
#include "int_lib.h"
COMPILER_RT_ABI fp_t __floatsisf(int a) {
const int aWidth = sizeof a * CHAR_BIT;
// Handle zero as a special case to protect clz
if (a == 0)
return fromRep(0);
// All other cases begin by extracting the sign and absolute value of a
rep_t sign = 0;
if (a < 0) {
sign = signBit;
a = -a;
}
// 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;
// Insert the sign bit and return
return fromRep(result | sign);
}
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_i2f(int a) { return __floatsisf(a); }
#else
COMPILER_RT_ALIAS(__floatsisf, __aeabi_i2f)
#endif
#endif

View File

@@ -1,57 +0,0 @@
//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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"
#include "int_lib.h"
COMPILER_RT_ABI 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);
}
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) { return __floatunsisf(a); }
#else
COMPILER_RT_ALIAS(__floatunsisf, __aeabi_ui2f)
#endif
#endif

View File

@@ -1,326 +0,0 @@
//===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a configuration header for soft-float routines in compiler-rt.
// This file does not provide any part of the compiler-rt interface, but defines
// many useful constants and utility routines that are used in the
// implementation of the soft-float routines in compiler-rt.
//
// Assumes that float, double and long double correspond to the IEEE-754
// binary32, binary64 and binary 128 types, respectively, and that integer
// endianness matches floating point endianness on the target platform.
//
//===----------------------------------------------------------------------===//
#ifndef FP_LIB_HEADER
#define FP_LIB_HEADER
#include "int_lib.h"
#include "int_math.h"
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
// x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in
// 32-bit mode.
#if defined(__FreeBSD__) && defined(__i386__)
#include <sys/param.h>
#if __FreeBSD_version < 903000 // v9.3
#define uint64_t unsigned long long
#define int64_t long long
#undef UINT64_C
#define UINT64_C(c) (c##ULL)
#endif
#endif
#if defined SINGLE_PRECISION
typedef uint16_t half_rep_t;
typedef uint32_t rep_t;
typedef uint64_t twice_rep_t;
typedef int32_t srep_t;
typedef float fp_t;
#define HALF_REP_C UINT16_C
#define REP_C UINT32_C
#define significandBits 23
static __inline int rep_clz(rep_t a) { return clzsi(a); }
// 32x32 --> 64 bit multiply
static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
const uint64_t product = (uint64_t)a * b;
*hi = product >> 32;
*lo = product;
}
COMPILER_RT_ABI fp_t __addsf3(fp_t a, fp_t b);
#elif defined DOUBLE_PRECISION
typedef uint32_t half_rep_t;
typedef uint64_t rep_t;
typedef int64_t srep_t;
typedef double fp_t;
#define HALF_REP_C UINT32_C
#define REP_C UINT64_C
#define significandBits 52
static __inline int rep_clz(rep_t a) {
#if defined __LP64__
return __builtin_clzl(a);
#else
if (a & REP_C(0xffffffff00000000))
return clzsi(a >> 32);
else
return 32 + clzsi(a & REP_C(0xffffffff));
#endif
}
#define loWord(a) (a & 0xffffffffU)
#define hiWord(a) (a >> 32)
// 64x64 -> 128 wide multiply for platforms that don't have such an operation;
// many 64-bit platforms have this operation, but they tend to have hardware
// floating-point, so we don't bother with a special case for them here.
static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
// Each of the component 32x32 -> 64 products
const uint64_t plolo = loWord(a) * loWord(b);
const uint64_t plohi = loWord(a) * hiWord(b);
const uint64_t philo = hiWord(a) * loWord(b);
const uint64_t phihi = hiWord(a) * hiWord(b);
// Sum terms that contribute to lo in a way that allows us to get the carry
const uint64_t r0 = loWord(plolo);
const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo);
*lo = r0 + (r1 << 32);
// Sum terms contributing to hi with the carry from lo
*hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi;
}
#undef loWord
#undef hiWord
COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b);
#elif defined QUAD_PRECISION
#if __LDBL_MANT_DIG__ == 113 && defined(__SIZEOF_INT128__)
#define CRT_LDBL_128BIT
typedef uint64_t half_rep_t;
typedef __uint128_t rep_t;
typedef __int128_t srep_t;
typedef long double fp_t;
#define HALF_REP_C UINT64_C
#define REP_C (__uint128_t)
// Note: Since there is no explicit way to tell compiler the constant is a
// 128-bit integer, we let the constant be casted to 128-bit integer
#define significandBits 112
static __inline int rep_clz(rep_t a) {
const union {
__uint128_t ll;
#if _YUGA_BIG_ENDIAN
struct {
uint64_t high, low;
} s;
#else
struct {
uint64_t low, high;
} s;
#endif
} uu = {.ll = a};
uint64_t word;
uint64_t add;
if (uu.s.high) {
word = uu.s.high;
add = 0;
} else {
word = uu.s.low;
add = 64;
}
return __builtin_clzll(word) + add;
}
#define Word_LoMask UINT64_C(0x00000000ffffffff)
#define Word_HiMask UINT64_C(0xffffffff00000000)
#define Word_FullMask UINT64_C(0xffffffffffffffff)
#define Word_1(a) (uint64_t)((a >> 96) & Word_LoMask)
#define Word_2(a) (uint64_t)((a >> 64) & Word_LoMask)
#define Word_3(a) (uint64_t)((a >> 32) & Word_LoMask)
#define Word_4(a) (uint64_t)(a & Word_LoMask)
// 128x128 -> 256 wide multiply for platforms that don't have such an operation;
// many 64-bit platforms have this operation, but they tend to have hardware
// floating-point, so we don't bother with a special case for them here.
static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
const uint64_t product11 = Word_1(a) * Word_1(b);
const uint64_t product12 = Word_1(a) * Word_2(b);
const uint64_t product13 = Word_1(a) * Word_3(b);
const uint64_t product14 = Word_1(a) * Word_4(b);
const uint64_t product21 = Word_2(a) * Word_1(b);
const uint64_t product22 = Word_2(a) * Word_2(b);
const uint64_t product23 = Word_2(a) * Word_3(b);
const uint64_t product24 = Word_2(a) * Word_4(b);
const uint64_t product31 = Word_3(a) * Word_1(b);
const uint64_t product32 = Word_3(a) * Word_2(b);
const uint64_t product33 = Word_3(a) * Word_3(b);
const uint64_t product34 = Word_3(a) * Word_4(b);
const uint64_t product41 = Word_4(a) * Word_1(b);
const uint64_t product42 = Word_4(a) * Word_2(b);
const uint64_t product43 = Word_4(a) * Word_3(b);
const uint64_t product44 = Word_4(a) * Word_4(b);
const __uint128_t sum0 = (__uint128_t)product44;
const __uint128_t sum1 = (__uint128_t)product34 + (__uint128_t)product43;
const __uint128_t sum2 =
(__uint128_t)product24 + (__uint128_t)product33 + (__uint128_t)product42;
const __uint128_t sum3 = (__uint128_t)product14 + (__uint128_t)product23 +
(__uint128_t)product32 + (__uint128_t)product41;
const __uint128_t sum4 =
(__uint128_t)product13 + (__uint128_t)product22 + (__uint128_t)product31;
const __uint128_t sum5 = (__uint128_t)product12 + (__uint128_t)product21;
const __uint128_t sum6 = (__uint128_t)product11;
const __uint128_t r0 = (sum0 & Word_FullMask) + ((sum1 & Word_LoMask) << 32);
const __uint128_t r1 = (sum0 >> 64) + ((sum1 >> 32) & Word_FullMask) +
(sum2 & Word_FullMask) + ((sum3 << 32) & Word_HiMask);
*lo = r0 + (r1 << 64);
*hi = (r1 >> 64) + (sum1 >> 96) + (sum2 >> 64) + (sum3 >> 32) + sum4 +
(sum5 << 32) + (sum6 << 64);
}
#undef Word_1
#undef Word_2
#undef Word_3
#undef Word_4
#undef Word_HiMask
#undef Word_LoMask
#undef Word_FullMask
#endif // __LDBL_MANT_DIG__ == 113 && __SIZEOF_INT128__
#else
#error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined.
#endif
#if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || \
defined(CRT_LDBL_128BIT)
#define typeWidth (sizeof(rep_t) * CHAR_BIT)
#define exponentBits (typeWidth - significandBits - 1)
#define maxExponent ((1 << exponentBits) - 1)
#define exponentBias (maxExponent >> 1)
#define implicitBit (REP_C(1) << significandBits)
#define significandMask (implicitBit - 1U)
#define signBit (REP_C(1) << (significandBits + exponentBits))
#define absMask (signBit - 1U)
#define exponentMask (absMask ^ significandMask)
#define oneRep ((rep_t)exponentBias << significandBits)
#define infRep exponentMask
#define quietBit (implicitBit >> 1)
#define qnanRep (exponentMask | quietBit)
static __inline rep_t toRep(fp_t x) {
const union {
fp_t f;
rep_t i;
} rep = {.f = x};
return rep.i;
}
static __inline fp_t fromRep(rep_t x) {
const union {
fp_t f;
rep_t i;
} rep = {.i = x};
return rep.f;
}
static __inline int normalize(rep_t *significand) {
const int shift = rep_clz(*significand) - rep_clz(implicitBit);
*significand <<= shift;
return 1 - shift;
}
static __inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) {
*hi = *hi << count | *lo >> (typeWidth - count);
*lo = *lo << count;
}
static __inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo,
unsigned int count) {
if (count < typeWidth) {
const bool sticky = (*lo << (typeWidth - count)) != 0;
*lo = *hi << (typeWidth - count) | *lo >> count | sticky;
*hi = *hi >> count;
} else if (count < 2 * typeWidth) {
const bool sticky = *hi << (2 * typeWidth - count) | *lo;
*lo = *hi >> (count - typeWidth) | sticky;
*hi = 0;
} else {
const bool sticky = *hi | *lo;
*lo = sticky;
*hi = 0;
}
}
// Implements logb methods (logb, logbf, logbl) for IEEE-754. This avoids
// pulling in a libm dependency from compiler-rt, but is not meant to replace
// it (i.e. code calling logb() should get the one from libm, not this), hence
// the __compiler_rt prefix.
static __inline fp_t __compiler_rt_logbX(fp_t x) {
rep_t rep = toRep(x);
int exp = (rep & exponentMask) >> significandBits;
// Abnormal cases:
// 1) +/- inf returns +inf; NaN returns NaN
// 2) 0.0 returns -inf
if (exp == maxExponent) {
if (((rep & signBit) == 0) || (x != x)) {
return x; // NaN or +inf: return x
} else {
return -x; // -inf: return -x
}
} else if (x == 0.0) {
// 0.0: return -inf
return fromRep(infRep | signBit);
}
if (exp != 0) {
// Normal number
return exp - exponentBias; // Unbias exponent
} else {
// Subnormal number; normalize and repeat
rep &= absMask;
const int shift = 1 - normalize(&rep);
exp = (rep & exponentMask) >> significandBits;
return exp - exponentBias - shift; // Unbias exponent
}
}
#endif
#if defined(SINGLE_PRECISION)
static __inline fp_t __compiler_rt_logbf(fp_t x) {
return __compiler_rt_logbX(x);
}
#elif defined(DOUBLE_PRECISION)
static __inline fp_t __compiler_rt_logb(fp_t x) {
return __compiler_rt_logbX(x);
}
#elif defined(QUAD_PRECISION)
#if defined(CRT_LDBL_128BIT)
static __inline fp_t __compiler_rt_logbl(fp_t x) {
return __compiler_rt_logbX(x);
}
#else
// The generic implementation only works for ieee754 floating point. For other
// floating point types, continue to rely on the libm implementation for now.
static __inline long double __compiler_rt_logbl(long double x) {
return crt_logbl(x);
}
#endif
#endif
#endif // FP_LIB_HEADER

View File

@@ -1,25 +0,0 @@
//===-- lib/mulsf3.c - Single-precision multiplication ------------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements single-precision soft-float multiplication
// with the IEEE-754 default rounding (to nearest, ties to even).
//
//===----------------------------------------------------------------------===//
#define SINGLE_PRECISION
#include "fp_mul_impl.inc"
COMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) { return __mulXf3__(a, b); }
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_fmul(fp_t a, fp_t b) { return __mulsf3(a, b); }
#else
COMPILER_RT_ALIAS(__mulsf3, __aeabi_fmul)
#endif
#endif

View File

@@ -1,27 +0,0 @@
//===-- lib/subsf3.c - Single-precision subtraction ---------------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements single-precision soft-float subtraction.
//
//===----------------------------------------------------------------------===//
#define SINGLE_PRECISION
#include "fp_lib.h"
// Subtraction; flip the sign bit of b and add.
COMPILER_RT_ABI fp_t __subsf3(fp_t a, fp_t b) {
return __addsf3(a, fromRep(toRep(b) ^ signBit));
}
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI fp_t __aeabi_fsub(fp_t a, fp_t b) { return __subsf3(a, b); }
#else
COMPILER_RT_ALIAS(__subsf3, __aeabi_fsub)
#endif
#endif

View File

@@ -24,7 +24,7 @@
static int outcol, outline, destcol, destline; static int outcol, outline, destcol, destline;
WINDOW *_win; extern WINDOW *_win;
/* /*
* Move (slowly) to destination. * Move (slowly) to destination.

View File

@@ -9,8 +9,8 @@
#define MAXRETURNSIZE 64 #define MAXRETURNSIZE 64
char *UP; extern char *UP;
char *BC; extern char *BC;
/* /*
* Routine to perform cursor addressing. * Routine to perform cursor addressing.

View File

@@ -16,8 +16,8 @@ static short tmspc10[] = {
0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
}; };
short ospeed; extern short ospeed;
char PC; extern char PC;
/* /*
* Put the character string cp out, with padding. * Put the character string cp out, with padding.

View File

@@ -60,7 +60,10 @@ ELF2AOUT = $(TOPSRC)/tools/elf2aout/elf2aout
CFLAGS = -Os -nostdinc CFLAGS = -Os -nostdinc
LDFLAGS = --nmagic -T$(TOPSRC)/src/elf32-mips.ld $(TOPSRC)/src/crt0.o -L$(TOPSRC)/src LDFLAGS = --nmagic -T$(TOPSRC)/src/elf32-mips.ld $(TOPSRC)/src/crt0.o -L$(TOPSRC)/src
LIBS = -lc -lclang LIBS = -lc
# Enable mips16e instruction set by default # Enable mips16e instruction set by default
#CFLAGS += -mips16 #CFLAGS += -mips16
# Catch all warnings
CC += -Werror