diff --git a/.gitignore b/.gitignore index b012372..6dbea89 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ *.img Makefile.user +TODO diff --git a/src/Makefile b/src/Makefile index 7fadd29..3fb4047 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,8 +9,7 @@ include $(TOPSRC)/target.mk # Programs that live in subdirectories, and have makefiles of their own. # SUBDIR = startup-$(MACHINE) libc libm libutil libtermlib libcurses \ - libvmf libwiznet libreadline libgpanel share cmd games man \ - libclang + libvmf libwiznet libreadline libgpanel share cmd games man all: $(SUBDIR) diff --git a/src/cmd/awk/Makefile b/src/cmd/awk/Makefile index dde0f75..f1ce292 100644 --- a/src/cmd/awk/Makefile +++ b/src/cmd/awk/Makefile @@ -5,7 +5,7 @@ CFLAGS += -Werror -Os YACC = bison -y 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 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 diff --git a/src/cmd/awk/proc.c b/src/cmd/awk/proc.c index 247015b..09305ea 100644 --- a/src/cmd/awk/proc.c +++ b/src/cmd/awk/proc.c @@ -30,7 +30,7 @@ struct xx { INDIRECT, "indirect", "$("}, { SUBSTR, "substr", "substr"}, { INDEX, "sindex", "sindex"}, - { SPRINTF, "asprintf", "sprintf "}, + { SPRINTF, "awksprintf", "sprintf "}, { ADD, "arith", " + "}, { MINUS, "arith", " - "}, { MULT, "arith", " * "}, diff --git a/src/cmd/awk/run.c b/src/cmd/awk/run.c index f5beaed..5195149 100644 --- a/src/cmd/awk/run.c +++ b/src/cmd/awk/run.c @@ -402,7 +402,7 @@ char *format(s,a) char *s; node *a; return(buf); } -obj asprintf1(a,n) node **a; +obj awksprintf(a,n) node **a; { obj x; node *y; @@ -597,7 +597,7 @@ obj aprintf(a,n) node **a; { obj x; - x = asprintf1(a,n); + x = awksprintf(a,n); if (a[1]==NULL) { printf("%s", x.optr->sval); tempfree(x); diff --git a/src/libc/Makefile b/src/libc/Makefile index 44cf99f..79ea6bc 100644 --- a/src/libc/Makefile +++ b/src/libc/Makefile @@ -27,7 +27,7 @@ TOPSRC = $(shell cd ../..; pwd) include $(TOPSRC)/target.mk DEFS = -Wall -Werror -ALL = gen stdio stdlib string inet compat ${MACHINE} +ALL = gen stdio stdlib string inet compat runtime ${MACHINE} all: ../libc.a diff --git a/src/libc/runtime/Makefile b/src/libc/runtime/Makefile index ca39b36..96eb6c0 100644 --- a/src/libc/runtime/Makefile +++ b/src/libc/runtime/Makefile @@ -19,20 +19,30 @@ include $(TOPSRC)/target.mk CFLAGS += ${DEFS} -OBJS = addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \ - mulsf3.o negsf2.o subsf3.o sc_case.o fixunssfsi.o \ - floatunsisf.o - -all: ${OBJS} +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 +runtime.a: ${OBJS} + @echo "buiding runtime.a" + @$(AR) cru runtime.a ${OBJS} clean: rm -f *.a *.o *~ profiled/*.o tags cleandir: clean 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 diff --git a/src/libc/runtime/README.txt b/src/libc/runtime/README.txt index b37c0ae..d66d725 100644 --- a/src/libc/runtime/README.txt +++ b/src/libc/runtime/README.txt @@ -20,13 +20,18 @@ 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 int si_int; -typedef unsigned su_int; +typedef int32_t si_int; +typedef uint32_t su_int; -typedef long long di_int; -typedef unsigned long long du_int; +typedef int64_t di_int; +typedef uint64_t du_int; // 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) ti_int __lshrti3(ti_int a, si_int b); // a >> b logical (zero fill) -si_int __clzsi2(si_int a); // count leading zeros -si_int __clzdi2(di_int a); // count leading zeros -si_int __clzti2(ti_int a); // count leading zeros -si_int __ctzsi2(si_int a); // count trailing zeros -si_int __ctzdi2(di_int a); // count trailing zeros -si_int __ctzti2(ti_int a); // count trailing zeros +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 -si_int __ffsdi2(di_int a); // find least significant 1 bit -si_int __ffsti2(ti_int a); // find least significant 1 bit +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 -si_int __paritysi2(si_int a); // bit parity -si_int __paritydi2(di_int a); // bit parity -si_int __parityti2(ti_int a); // bit parity +int __paritysi2(si_int a); // bit parity +int __paritydi2(di_int a); // bit parity +int __parityti2(ti_int a); // bit parity -si_int __popcountsi2(si_int a); // bit population -si_int __popcountdi2(di_int a); // bit population -si_int __popcountti2(ti_int a); // bit population +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, arm only -uint64_t __bswapdi2(uint64_t a); // a byteswapped, arm only +uint32_t __bswapsi2(uint32_t a); // a byteswapped +uint64_t __bswapdi2(uint64_t a); // a byteswapped // 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 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 @@ -168,10 +176,10 @@ long double __floatuntixf(tu_int a); // Floating point raised to integer power -float __powisf2( float a, si_int b); // a ^ b -double __powidf2( double a, si_int b); // a ^ b -long double __powixf2(long double a, si_int b); // a ^ b -long double __powitf2(long double a, si_int b); // ppc only, a ^ b +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 @@ -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 // 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); // __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 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 diff --git a/src/libclang/adddf3.c b/src/libc/runtime/adddf3.c similarity index 100% rename from src/libclang/adddf3.c rename to src/libc/runtime/adddf3.c diff --git a/src/libc/runtime/addsf3.c b/src/libc/runtime/addsf3.c index 0394b35..9f1d517 100644 --- a/src/libc/runtime/addsf3.c +++ b/src/libc/runtime/addsf3.c @@ -1,150 +1,24 @@ //===-- lib/addsf3.c - Single-precision addition ------------------*- 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. +// 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 with the IEEE-754 -// default rounding (to nearest, ties to even). +// This file implements single-precision soft-float addition. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION -#include "fp_lib.h" +#include "fp_add_impl.inc" -fp_t -__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; +COMPILER_RT_ABI float __addsf3(float a, float b) { return __addXf3__(a, b); } - // Detect if a or b is zero, infinity, or NaN. - if (aAbs - 1U >= infRep - 1U || bAbs - 1U >= infRep - 1U) { - - // 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 + -/+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); -} +#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 diff --git a/src/libclang/comparedf2.c b/src/libc/runtime/comparedf2.c similarity index 100% rename from src/libclang/comparedf2.c rename to src/libc/runtime/comparedf2.c diff --git a/src/libc/runtime/comparesf2.c b/src/libc/runtime/comparesf2.c index 83f87f8..1cb99e4 100644 --- a/src/libc/runtime/comparesf2.c +++ b/src/libc/runtime/comparesf2.c @@ -1,9 +1,8 @@ //===-- lib/comparesf2.c - Single-precision comparisons -----------*- 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. +// 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 // //===----------------------------------------------------------------------===// // @@ -40,104 +39,113 @@ #define SINGLE_PRECISION #include "fp_lib.h" -enum LE_RESULT { - LE_LESS = -1, - LE_EQUAL = 0, - LE_GREATER = 1, - LE_UNORDERED = 1 -}; +enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 }; -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; +COMPILER_RT_ABI enum LE_RESULT __lesf2(fp_t a, fp_t b) { - // If either a or b is NaN, they are unordered. - if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; + 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 a and b are both zeros, they are equal. - if ((aAbs | bAbs) == 0) return LE_EQUAL; + // If either a or b is NaN, they are unordered. + if (aAbs > infRep || bAbs > infRep) + return LE_UNORDERED; - // 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; - } + // If a and b are both zeros, they are equal. + if ((aAbs | bAbs) == 0) + return LE_EQUAL; - // 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 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 + GE_LESS = -1, + GE_EQUAL = 0, + GE_GREATER = 1, + GE_UNORDERED = -1 // Note: different from LE_UNORDERED }; -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; +COMPILER_RT_ABI enum GE_RESULT __gesf2(fp_t a, fp_t b) { - 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; - } + 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; + } } -int -__unordsf2(fp_t a, fp_t b) -{ +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; } -// 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 -__eqsf2(fp_t a, fp_t b) -{ - return __lesf2(a, b); -} - -enum LE_RESULT -__ltsf2(fp_t a, fp_t b) -{ - 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); -} +#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 diff --git a/src/libclang/divdf3.c b/src/libc/runtime/divdf3.c similarity index 100% rename from src/libclang/divdf3.c rename to src/libc/runtime/divdf3.c diff --git a/src/libc/runtime/divsf3.c b/src/libc/runtime/divsf3.c index 57178ad..5744c01 100644 --- a/src/libc/runtime/divsf3.c +++ b/src/libc/runtime/divsf3.c @@ -1,165 +1,30 @@ //===-- lib/divsf3.c - Single-precision division ------------------*- 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. +// 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). // -// 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 -#include "fp_lib.h" -fp_t -__divsf3(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 quotientSign = (toRep(a) ^ toRep(b)) & signBit; +#define NUMBER_OF_HALF_ITERATIONS 0 +#define NUMBER_OF_FULL_ITERATIONS 3 +#define USE_NATIVE_FULL_ITERATIONS - rep_t aSignificand = toRep(a) & significandMask; - rep_t bSignificand = toRep(b) & significandMask; - int scale = 0; +#include "fp_div_impl.inc" - // Detect if a or b is zero, denormal, infinity, or NaN. - if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { +COMPILER_RT_ABI fp_t __divsf3(fp_t a, fp_t b) { return __divXf3__(a, b); } - 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 / 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); - } -} +#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 diff --git a/src/libclang/extendsfdf2.c b/src/libc/runtime/extendsfdf2.c similarity index 100% rename from src/libclang/extendsfdf2.c rename to src/libc/runtime/extendsfdf2.c diff --git a/src/libclang/fixdfsi.c b/src/libc/runtime/fixdfsi.c similarity index 100% rename from src/libclang/fixdfsi.c rename to src/libc/runtime/fixdfsi.c diff --git a/src/libc/runtime/fixsfsi.c b/src/libc/runtime/fixsfsi.c index e683d55..d83d7e7 100644 --- a/src/libc/runtime/fixsfsi.c +++ b/src/libc/runtime/fixsfsi.c @@ -1,46 +1,23 @@ -//===-- lib/fixsfsi.c - Single-precision -> integer conversion ----*- C -*-===// +//===-- fixsfsi.c - Implement __fixsfsi -----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// 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. +// 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" -int -__fixsfsi(fp_t a) -{ - // Break a into sign, exponent, significand - const rep_t aRep = toRep(a); - const rep_t aAbs = aRep & absMask; - const int sign = aRep & signBit ? -1 : 1; - const int exponent = (aAbs >> significandBits) - exponentBias; - const rep_t significand = (aAbs & significandMask) | implicitBit; +COMPILER_RT_ABI si_int __fixsfsi(fp_t a) { return __fixint(a); } - // If 0 < exponent < significandBits, right shift to get the result. - if ((unsigned int)exponent < significandBits) { - return sign * (significand >> (significandBits - exponent)); - } - - // If exponent is negative, the result is zero. - else if (exponent < 0) { - return 0; - } - - // If significandBits < exponent, left shift to get the result. This shift - // may end up being larger than the type width, which incurs undefined - // behavior, but the conversion itself is undefined in that case, so - // whatever the compiler decides to do is fine. - else { - return sign * (significand << (exponent - significandBits)); - } -} +#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 diff --git a/src/libc/runtime/fixunssfsi.c b/src/libc/runtime/fixunssfsi.c deleted file mode 100644 index be0cde4..0000000 --- a/src/libc/runtime/fixunssfsi.c +++ /dev/null @@ -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; -} diff --git a/src/libclang/floatsidf.c b/src/libc/runtime/floatsidf.c similarity index 100% rename from src/libclang/floatsidf.c rename to src/libc/runtime/floatsidf.c diff --git a/src/libc/runtime/floatsisf.c b/src/libc/runtime/floatsisf.c index 365e78a..fe06040 100644 --- a/src/libc/runtime/floatsisf.c +++ b/src/libc/runtime/floatsisf.c @@ -1,9 +1,8 @@ //===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,40 +15,51 @@ #define SINGLE_PRECISION #include "fp_lib.h" -fp_t -__floatsisf(int a) -{ - const int aWidth = sizeof a * CHAR_BIT; +#include "int_lib.h" - // Handle zero as a special case to protect clz - if (a == 0) - return fromRep(0); +COMPILER_RT_ABI fp_t __floatsisf(int a) { - // All other cases begin by extracting the sign and absolute value of a - rep_t sign = 0; - if (a < 0) { - sign = signBit; - a = -a; - } + const int aWidth = sizeof a * CHAR_BIT; - // Exponent of (fp_t)a is the width of abs(a). - const int exponent = (aWidth - 1) - __builtin_clz(a); - rep_t result; + // Handle zero as a special case to protect clz + if (a == 0) + return fromRep(0); - // 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; - } + // All other cases begin by extracting the sign and absolute value of a + rep_t sign = 0; + if (a < 0) { + sign = signBit; + a = -a; + } - // Insert the exponent - result += (rep_t)(exponent + exponentBias) << significandBits; - // Insert the sign bit and return - return fromRep(result | sign); + // 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 diff --git a/src/libc/runtime/floatunsisf.c b/src/libc/runtime/floatunsisf.c index a61066c..33a1b5a 100644 --- a/src/libc/runtime/floatunsisf.c +++ b/src/libc/runtime/floatunsisf.c @@ -1,9 +1,8 @@ //===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,32 +15,43 @@ #define SINGLE_PRECISION #include "fp_lib.h" -fp_t -__floatunsisf(unsigned int a) -{ - const int aWidth = sizeof a * CHAR_BIT; +#include "int_lib.h" - // Handle zero as a special case to protect clz - if (a == 0) - return fromRep(0); +COMPILER_RT_ABI fp_t __floatunsisf(unsigned int a) { - // Exponent of (fp_t)a is the width of abs(a). - const int exponent = (aWidth - 1) - __builtin_clz(a); - rep_t result; + const int aWidth = sizeof a * CHAR_BIT; - // 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; - } + // Handle zero as a special case to protect clz + if (a == 0) + return fromRep(0); - // Insert the exponent - result += (rep_t)(exponent + exponentBias) << significandBits; - return fromRep(result); + // 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 diff --git a/src/libclang/fp_add_impl.inc b/src/libc/runtime/fp_add_impl.inc similarity index 100% rename from src/libclang/fp_add_impl.inc rename to src/libc/runtime/fp_add_impl.inc diff --git a/src/libclang/fp_div_impl.inc b/src/libc/runtime/fp_div_impl.inc similarity index 100% rename from src/libclang/fp_div_impl.inc rename to src/libc/runtime/fp_div_impl.inc diff --git a/src/libclang/fp_extend.h b/src/libc/runtime/fp_extend.h similarity index 100% rename from src/libclang/fp_extend.h rename to src/libc/runtime/fp_extend.h diff --git a/src/libclang/fp_extend_impl.inc b/src/libc/runtime/fp_extend_impl.inc similarity index 100% rename from src/libclang/fp_extend_impl.inc rename to src/libc/runtime/fp_extend_impl.inc diff --git a/src/libclang/fp_fixint_impl.inc b/src/libc/runtime/fp_fixint_impl.inc similarity index 100% rename from src/libclang/fp_fixint_impl.inc rename to src/libc/runtime/fp_fixint_impl.inc diff --git a/src/libc/runtime/fp_lib.h b/src/libc/runtime/fp_lib.h index 35d7a2c..f22feaf 100644 --- a/src/libc/runtime/fp_lib.h +++ b/src/libc/runtime/fp_lib.h @@ -1,9 +1,8 @@ //===-- lib/fp_lib.h - Floating-point utilities -------------------*- 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. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,60 +11,72 @@ // many useful constants and utility routines that are used in the // implementation of the soft-float routines in compiler-rt. // -// Assumes that float and double correspond to the IEEE-754 binary32 and -// binary64 types, respectively, and that integer endianness matches floating -// point endianness on the target platform. +// 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 +#include "int_lib.h" +#include "int_math.h" #include +#include +#include -typedef unsigned long long uint64_t; - -#define UINT32_C(x) (x##U) +// x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in +// 32-bit mode. +#if defined(__FreeBSD__) && defined(__i386__) +#include +#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 __builtin_clz(a); -} +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; +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) -{ +static __inline int rep_clz(rep_t a) { #if defined __LP64__ - return __builtin_clzl(a); + return __builtin_clzl(a); #else - if (a & REP_C(0xffffffff00000000)) - return __builtin_clz(a >> 32); - else - return 32 + __builtin_clz(a & REP_C(0xffffffff)); + if (a & REP_C(0xffffffff00000000)) + return clzsi(a >> 32); + else + return 32 + clzsi(a & REP_C(0xffffffff)); #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; // 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; +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 Either SINGLE_PRECISION or DOUBLE_PRECISION must be defined. +#error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined. #endif -#define typeWidth (sizeof(rep_t)*CHAR_BIT) -#define exponentBits (typeWidth - significandBits - 1) -#define maxExponent ((1 << exponentBits) - 1) -#define exponentBias (maxExponent >> 1) +#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 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) +#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 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 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 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 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) { - int sticky = (*lo << (typeWidth - count)) != 0; - *lo = *hi << (typeWidth - count) | *lo >> count | sticky; - *hi = *hi >> count; - } - else if (count < 2*typeWidth) { - int sticky = (*hi << (2*typeWidth - count) | *lo) != 0; - *lo = *hi >> (count - typeWidth) | sticky; - *hi = 0; +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 { - int sticky = (*hi | *lo) != 0; - *lo = sticky; - *hi = 0; + 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 diff --git a/src/libclang/fp_mode.c b/src/libc/runtime/fp_mode.c similarity index 100% rename from src/libclang/fp_mode.c rename to src/libc/runtime/fp_mode.c diff --git a/src/libclang/fp_mode.h b/src/libc/runtime/fp_mode.h similarity index 100% rename from src/libclang/fp_mode.h rename to src/libc/runtime/fp_mode.h diff --git a/src/libclang/fp_mul_impl.inc b/src/libc/runtime/fp_mul_impl.inc similarity index 100% rename from src/libclang/fp_mul_impl.inc rename to src/libc/runtime/fp_mul_impl.inc diff --git a/src/libclang/fp_trunc.h b/src/libc/runtime/fp_trunc.h similarity index 100% rename from src/libclang/fp_trunc.h rename to src/libc/runtime/fp_trunc.h diff --git a/src/libclang/fp_trunc_impl.inc b/src/libc/runtime/fp_trunc_impl.inc similarity index 100% rename from src/libclang/fp_trunc_impl.inc rename to src/libc/runtime/fp_trunc_impl.inc diff --git a/src/libclang/int_endianness.h b/src/libc/runtime/int_endianness.h similarity index 100% rename from src/libclang/int_endianness.h rename to src/libc/runtime/int_endianness.h diff --git a/src/libclang/int_lib.h b/src/libc/runtime/int_lib.h similarity index 100% rename from src/libclang/int_lib.h rename to src/libc/runtime/int_lib.h diff --git a/src/libclang/int_math.h b/src/libc/runtime/int_math.h similarity index 100% rename from src/libclang/int_math.h rename to src/libc/runtime/int_math.h diff --git a/src/libclang/int_types.h b/src/libc/runtime/int_types.h similarity index 100% rename from src/libclang/int_types.h rename to src/libc/runtime/int_types.h diff --git a/src/libclang/int_util.h b/src/libc/runtime/int_util.h similarity index 100% rename from src/libclang/int_util.h rename to src/libc/runtime/int_util.h diff --git a/src/libclang/muldf3.c b/src/libc/runtime/muldf3.c similarity index 100% rename from src/libclang/muldf3.c rename to src/libc/runtime/muldf3.c diff --git a/src/libc/runtime/mulsf3.c b/src/libc/runtime/mulsf3.c index 0b848fb..b9cf39a 100644 --- a/src/libc/runtime/mulsf3.c +++ b/src/libc/runtime/mulsf3.c @@ -1,9 +1,8 @@ //===-- lib/mulsf3.c - Single-precision multiplication ------------*- 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. +// 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 // //===----------------------------------------------------------------------===// // @@ -13,98 +12,14 @@ //===----------------------------------------------------------------------===// #define SINGLE_PRECISION -#include "fp_lib.h" +#include "fp_mul_impl.inc" -fp_t -__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; +COMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) { return __mulXf3__(a, b); } - rep_t aSignificand = toRep(a) & significandMask; - rep_t bSignificand = toRep(b) & significandMask; - int scale = 0; - - // Detect if a or b is zero, denormal, infinity, or NaN. - if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { - - 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); -} +#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 diff --git a/src/libc/runtime/negsf2.c b/src/libc/runtime/negsf2.c deleted file mode 100644 index ed7ba4c..0000000 --- a/src/libc/runtime/negsf2.c +++ /dev/null @@ -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); -} diff --git a/src/libclang/subdf3.c b/src/libc/runtime/subdf3.c similarity index 100% rename from src/libclang/subdf3.c rename to src/libc/runtime/subdf3.c diff --git a/src/libc/runtime/subsf3.c b/src/libc/runtime/subsf3.c index ff1dd94..ecfc24f 100644 --- a/src/libc/runtime/subsf3.c +++ b/src/libc/runtime/subsf3.c @@ -1,25 +1,27 @@ //===-- lib/subsf3.c - Single-precision subtraction ---------------*- 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. +// 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 with the -// IEEE-754 default rounding (to nearest, ties to even). +// This file implements single-precision soft-float subtraction. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" -fp_t __addsf3(fp_t a, fp_t b); - // Subtraction; flip the sign bit of b and add. -fp_t -__subsf3(fp_t a, fp_t b) -{ - return __addsf3(a, fromRep(toRep(b) ^ signBit)); +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 diff --git a/src/libclang/truncdfsf2.c b/src/libc/runtime/truncdfsf2.c similarity index 100% rename from src/libclang/truncdfsf2.c rename to src/libc/runtime/truncdfsf2.c diff --git a/src/libclang/Makefile b/src/libclang/Makefile deleted file mode 100644 index 2a377c3..0000000 --- a/src/libclang/Makefile +++ /dev/null @@ -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 diff --git a/src/libclang/README.txt b/src/libclang/README.txt deleted file mode 100644 index d66d725..0000000 --- a/src/libclang/README.txt +++ /dev/null @@ -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 -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. diff --git a/src/libclang/addsf3.c b/src/libclang/addsf3.c deleted file mode 100644 index 9f1d517..0000000 --- a/src/libclang/addsf3.c +++ /dev/null @@ -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 diff --git a/src/libclang/comparesf2.c b/src/libclang/comparesf2.c deleted file mode 100644 index 1cb99e4..0000000 --- a/src/libclang/comparesf2.c +++ /dev/null @@ -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 diff --git a/src/libclang/divsf3.c b/src/libclang/divsf3.c deleted file mode 100644 index 5744c01..0000000 --- a/src/libclang/divsf3.c +++ /dev/null @@ -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 diff --git a/src/libclang/fixsfsi.c b/src/libclang/fixsfsi.c deleted file mode 100644 index d83d7e7..0000000 --- a/src/libclang/fixsfsi.c +++ /dev/null @@ -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 diff --git a/src/libclang/floatsisf.c b/src/libclang/floatsisf.c deleted file mode 100644 index fe06040..0000000 --- a/src/libclang/floatsisf.c +++ /dev/null @@ -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 diff --git a/src/libclang/floatunsisf.c b/src/libclang/floatunsisf.c deleted file mode 100644 index 33a1b5a..0000000 --- a/src/libclang/floatunsisf.c +++ /dev/null @@ -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 diff --git a/src/libclang/fp_lib.h b/src/libclang/fp_lib.h deleted file mode 100644 index f22feaf..0000000 --- a/src/libclang/fp_lib.h +++ /dev/null @@ -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 -#include -#include - -// x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in -// 32-bit mode. -#if defined(__FreeBSD__) && defined(__i386__) -#include -#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 diff --git a/src/libclang/mulsf3.c b/src/libclang/mulsf3.c deleted file mode 100644 index b9cf39a..0000000 --- a/src/libclang/mulsf3.c +++ /dev/null @@ -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 diff --git a/src/libclang/subsf3.c b/src/libclang/subsf3.c deleted file mode 100644 index ecfc24f..0000000 --- a/src/libclang/subsf3.c +++ /dev/null @@ -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 diff --git a/src/libcurses/cr_put.c b/src/libcurses/cr_put.c index 036c042..98a4d14 100644 --- a/src/libcurses/cr_put.c +++ b/src/libcurses/cr_put.c @@ -24,7 +24,7 @@ static int outcol, outline, destcol, destline; -WINDOW *_win; +extern WINDOW *_win; /* * Move (slowly) to destination. diff --git a/src/libtermlib/tgoto.c b/src/libtermlib/tgoto.c index f8ad1a4..cb9d099 100644 --- a/src/libtermlib/tgoto.c +++ b/src/libtermlib/tgoto.c @@ -9,8 +9,8 @@ #define MAXRETURNSIZE 64 -char *UP; -char *BC; +extern char *UP; +extern char *BC; /* * Routine to perform cursor addressing. diff --git a/src/libtermlib/tputs.c b/src/libtermlib/tputs.c index cdbddde..7fc9340 100644 --- a/src/libtermlib/tputs.c +++ b/src/libtermlib/tputs.c @@ -16,8 +16,8 @@ static short tmspc10[] = { 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5 }; -short ospeed; -char PC; +extern short ospeed; +extern char PC; /* * Put the character string cp out, with padding. diff --git a/target.mk b/target.mk index 63ac502..2b30215 100644 --- a/target.mk +++ b/target.mk @@ -60,7 +60,10 @@ ELF2AOUT = $(TOPSRC)/tools/elf2aout/elf2aout CFLAGS = -Os -nostdinc 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 #CFLAGS += -mips16 + +# Catch all warnings +CC += -Werror