mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 05:42:29 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
32
third_party/compiler_rt/absvdi2.c
vendored
Normal file
32
third_party/compiler_rt/absvdi2.c
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* clang-format off */
|
||||
/*===-- absvdi2.c - Implement __absvdi2 -----------------------------------===
|
||||
*
|
||||
* 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 __absvdi2 for the compiler_rt library.
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: absolute value */
|
||||
|
||||
/* Effects: aborts if abs(x) < 0 */
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__absvdi2(di_int a)
|
||||
{
|
||||
const int N = (int)(sizeof(di_int) * CHAR_BIT);
|
||||
if (a == ((di_int)1 << (N-1)))
|
||||
compilerrt_abort();
|
||||
const di_int t = a >> (N - 1);
|
||||
return (a ^ t) - t;
|
||||
}
|
32
third_party/compiler_rt/absvsi2.c
vendored
Normal file
32
third_party/compiler_rt/absvsi2.c
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* clang-format off */
|
||||
/* ===-- absvsi2.c - Implement __absvsi2 -----------------------------------===
|
||||
*
|
||||
* 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 __absvsi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: absolute value */
|
||||
|
||||
/* Effects: aborts if abs(x) < 0 */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__absvsi2(si_int a)
|
||||
{
|
||||
const int N = (int)(sizeof(si_int) * CHAR_BIT);
|
||||
if (a == (1 << (N-1)))
|
||||
compilerrt_abort();
|
||||
const si_int t = a >> (N - 1);
|
||||
return (a ^ t) - t;
|
||||
}
|
37
third_party/compiler_rt/absvti2.c
vendored
Normal file
37
third_party/compiler_rt/absvti2.c
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* clang-format off */
|
||||
/* ===-- absvti2.c - Implement __absvdi2 -----------------------------------===
|
||||
*
|
||||
* 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 __absvti2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: absolute value */
|
||||
|
||||
/* Effects: aborts if abs(x) < 0 */
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__absvti2(ti_int a)
|
||||
{
|
||||
const int N = (int)(sizeof(ti_int) * CHAR_BIT);
|
||||
if (a == ((ti_int)1 << (N-1)))
|
||||
compilerrt_abort();
|
||||
const ti_int s = a >> (N - 1);
|
||||
return (a ^ s) - s;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
||||
|
33
third_party/compiler_rt/adddf3.c
vendored
Normal file
33
third_party/compiler_rt/adddf3.c
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/adddf3.c - Double-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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements double-precision soft-float addition with the IEEE-754
|
||||
// default rounding (to nearest, ties to even).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_add_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI double __adddf3(double a, double b){
|
||||
return __addXf3__(a, b);
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI double __aeabi_dadd(double a, double b) {
|
||||
return __adddf3(a, b);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI double __aeabi_dadd(double a, double b) COMPILER_RT_ALIAS(__adddf3);
|
||||
#endif
|
||||
#endif
|
33
third_party/compiler_rt/addsf3.c
vendored
Normal file
33
third_party/compiler_rt/addsf3.c
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* clang-format off */
|
||||
//===-- 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements single-precision soft-float addition with the IEEE-754
|
||||
// default rounding (to nearest, ties to even).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/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
|
||||
AEABI_RTABI float __aeabi_fadd(float a, float b) COMPILER_RT_ALIAS(__addsf3);
|
||||
#endif
|
||||
#endif
|
28
third_party/compiler_rt/addtf3.c
vendored
Normal file
28
third_party/compiler_rt/addtf3.c
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/addtf3.c - Quad-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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements quad-precision soft-float addition with the IEEE-754
|
||||
// default rounding (to nearest, ties to even).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
#include "third_party/compiler_rt/fp_add_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI long double __addtf3(long double a, long double b){
|
||||
return __addXf3__(a, b);
|
||||
}
|
||||
|
||||
#endif
|
48
third_party/compiler_rt/ashldi3.c
vendored
Normal file
48
third_party/compiler_rt/ashldi3.c
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* clang-format off */
|
||||
/* ====-- ashldi3.c - Implement __ashldi3 -----------------------------------===
|
||||
*
|
||||
* 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 __ashldi3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: a << b */
|
||||
|
||||
/* Precondition: 0 <= b < bits_in_dword */
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__ashldi3(di_int a, si_int b)
|
||||
{
|
||||
const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
|
||||
dwords input;
|
||||
dwords result;
|
||||
input.all = a;
|
||||
if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */
|
||||
{
|
||||
result.s.low = 0;
|
||||
result.s.high = input.s.low << (b - bits_in_word);
|
||||
}
|
||||
else /* 0 <= b < bits_in_word */
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
result.s.low = input.s.low << b;
|
||||
result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_word - b));
|
||||
}
|
||||
return result.all;
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
AEABI_RTABI di_int __aeabi_llsl(di_int a, si_int b) COMPILER_RT_ALIAS(__ashldi3);
|
||||
#endif
|
48
third_party/compiler_rt/ashlti3.c
vendored
Normal file
48
third_party/compiler_rt/ashlti3.c
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* clang-format off */
|
||||
/* ===-- ashlti3.c - Implement __ashlti3 -----------------------------------===
|
||||
*
|
||||
* 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 __ashlti3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: a << b */
|
||||
|
||||
/* Precondition: 0 <= b < bits_in_tword */
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__ashlti3(ti_int a, si_int b)
|
||||
{
|
||||
const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);
|
||||
twords input;
|
||||
twords result;
|
||||
input.all = a;
|
||||
if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */
|
||||
{
|
||||
result.s.low = 0;
|
||||
result.s.high = input.s.low << (b - bits_in_dword);
|
||||
}
|
||||
else /* 0 <= b < bits_in_dword */
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
result.s.low = input.s.low << b;
|
||||
result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_dword - b));
|
||||
}
|
||||
return result.all;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
49
third_party/compiler_rt/ashrdi3.c
vendored
Normal file
49
third_party/compiler_rt/ashrdi3.c
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* clang-format off */
|
||||
/*===-- ashrdi3.c - Implement __ashrdi3 -----------------------------------===
|
||||
*
|
||||
* 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 __ashrdi3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: arithmetic a >> b */
|
||||
|
||||
/* Precondition: 0 <= b < bits_in_dword */
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__ashrdi3(di_int a, si_int b)
|
||||
{
|
||||
const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
|
||||
dwords input;
|
||||
dwords result;
|
||||
input.all = a;
|
||||
if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */
|
||||
{
|
||||
/* result.s.high = input.s.high < 0 ? -1 : 0 */
|
||||
result.s.high = input.s.high >> (bits_in_word - 1);
|
||||
result.s.low = input.s.high >> (b - bits_in_word);
|
||||
}
|
||||
else /* 0 <= b < bits_in_word */
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
result.s.high = input.s.high >> b;
|
||||
result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b);
|
||||
}
|
||||
return result.all;
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
AEABI_RTABI di_int __aeabi_lasr(di_int a, si_int b) COMPILER_RT_ALIAS(__ashrdi3);
|
||||
#endif
|
49
third_party/compiler_rt/ashrti3.c
vendored
Normal file
49
third_party/compiler_rt/ashrti3.c
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* clang-format off */
|
||||
/* ===-- ashrti3.c - Implement __ashrti3 -----------------------------------===
|
||||
*
|
||||
* 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 __ashrti3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: arithmetic a >> b */
|
||||
|
||||
/* Precondition: 0 <= b < bits_in_tword */
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__ashrti3(ti_int a, si_int b)
|
||||
{
|
||||
const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);
|
||||
twords input;
|
||||
twords result;
|
||||
input.all = a;
|
||||
if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */
|
||||
{
|
||||
/* result.s.high = input.s.high < 0 ? -1 : 0 */
|
||||
result.s.high = input.s.high >> (bits_in_dword - 1);
|
||||
result.s.low = input.s.high >> (b - bits_in_dword);
|
||||
}
|
||||
else /* 0 <= b < bits_in_dword */
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
result.s.high = input.s.high >> b;
|
||||
result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b);
|
||||
}
|
||||
return result.all;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
205
third_party/compiler_rt/assembly.h
vendored
Normal file
205
third_party/compiler_rt/assembly.h
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
/* clang-format off */
|
||||
/* ===-- assembly.h - compiler-rt assembler support macros -----------------===
|
||||
*
|
||||
* 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 defines macros for use in compiler-rt assembler source.
|
||||
* This file is not part of the interface of this library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef COMPILERRT_ASSEMBLY_H
|
||||
#define COMPILERRT_ASSEMBLY_H
|
||||
|
||||
#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
|
||||
#define SEPARATOR @
|
||||
#else
|
||||
#define SEPARATOR ;
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#define HIDDEN(name) .private_extern name
|
||||
#define LOCAL_LABEL(name) L_##name
|
||||
// tell linker it can break up file at label boundaries
|
||||
#define FILE_LEVEL_DIRECTIVE .subsections_via_symbols
|
||||
#define SYMBOL_IS_FUNC(name)
|
||||
#define CONST_SECTION .const
|
||||
|
||||
#define NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
#elif defined(__ELF__)
|
||||
|
||||
#define HIDDEN(name) .hidden name
|
||||
#define LOCAL_LABEL(name) .L_##name
|
||||
#define FILE_LEVEL_DIRECTIVE
|
||||
#if defined(__arm__)
|
||||
#define SYMBOL_IS_FUNC(name) .type name,%function
|
||||
#else
|
||||
#define SYMBOL_IS_FUNC(name) .type name,@function
|
||||
#endif
|
||||
#define CONST_SECTION .section .rodata
|
||||
|
||||
#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
|
||||
defined(__linux__)
|
||||
#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
|
||||
#else
|
||||
#define NO_EXEC_STACK_DIRECTIVE
|
||||
#endif
|
||||
|
||||
#else // !__APPLE__ && !__ELF__
|
||||
|
||||
#define HIDDEN(name)
|
||||
#define LOCAL_LABEL(name) .L ## name
|
||||
#define FILE_LEVEL_DIRECTIVE
|
||||
#define SYMBOL_IS_FUNC(name) \
|
||||
.def name SEPARATOR \
|
||||
.scl 2 SEPARATOR \
|
||||
.type 32 SEPARATOR \
|
||||
.endef
|
||||
#define CONST_SECTION .section .rdata,"rd"
|
||||
|
||||
#define NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__arm__)
|
||||
|
||||
/*
|
||||
* Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros:
|
||||
* - for '-mthumb -march=armv6' compiler defines '__thumb__'
|
||||
* - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__'
|
||||
*/
|
||||
#if defined(__thumb2__) || defined(__thumb__)
|
||||
#define DEFINE_CODE_STATE .thumb SEPARATOR
|
||||
#define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR
|
||||
#if defined(__thumb2__)
|
||||
#define USE_THUMB_2
|
||||
#define IT(cond) it cond
|
||||
#define ITT(cond) itt cond
|
||||
#define ITE(cond) ite cond
|
||||
#else
|
||||
#define USE_THUMB_1
|
||||
#define IT(cond)
|
||||
#define ITT(cond)
|
||||
#define ITE(cond)
|
||||
#endif // defined(__thumb__2)
|
||||
#else // !defined(__thumb2__) && !defined(__thumb__)
|
||||
#define DEFINE_CODE_STATE .arm SEPARATOR
|
||||
#define DECLARE_FUNC_ENCODING
|
||||
#define IT(cond)
|
||||
#define ITT(cond)
|
||||
#define ITE(cond)
|
||||
#endif
|
||||
|
||||
#if defined(USE_THUMB_1) && defined(USE_THUMB_2)
|
||||
#error "USE_THUMB_1 and USE_THUMB_2 can't be defined together."
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
|
||||
#define ARM_HAS_BX
|
||||
#endif
|
||||
#if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \
|
||||
(__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__)))
|
||||
#define __ARM_FEATURE_CLZ
|
||||
#endif
|
||||
|
||||
#ifdef ARM_HAS_BX
|
||||
#define JMP(r) bx r
|
||||
#define JMPc(r, c) bx##c r
|
||||
#else
|
||||
#define JMP(r) mov pc, r
|
||||
#define JMPc(r, c) mov##c pc, r
|
||||
#endif
|
||||
|
||||
// pop {pc} can't switch Thumb mode on ARMv4T
|
||||
#if __ARM_ARCH >= 5
|
||||
#define POP_PC() pop {pc}
|
||||
#else
|
||||
#define POP_PC() \
|
||||
pop {ip}; \
|
||||
JMP(ip)
|
||||
#endif
|
||||
|
||||
#if defined(USE_THUMB_2)
|
||||
#define WIDE(op) op.w
|
||||
#else
|
||||
#define WIDE(op) op
|
||||
#endif
|
||||
#else // !defined(__arm)
|
||||
#define DECLARE_FUNC_ENCODING
|
||||
#define DEFINE_CODE_STATE
|
||||
#endif
|
||||
|
||||
#define GLUE2(a, b) a##b
|
||||
#define GLUE(a, b) GLUE2(a, b)
|
||||
#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
|
||||
|
||||
#ifdef VISIBILITY_HIDDEN
|
||||
#define DECLARE_SYMBOL_VISIBILITY(name) \
|
||||
HIDDEN(SYMBOL_NAME(name)) SEPARATOR
|
||||
#else
|
||||
#define DECLARE_SYMBOL_VISIBILITY(name)
|
||||
#endif
|
||||
|
||||
#define DEFINE_COMPILERRT_FUNCTION(name) \
|
||||
DEFINE_CODE_STATE \
|
||||
FILE_LEVEL_DIRECTIVE SEPARATOR \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
|
||||
DECLARE_SYMBOL_VISIBILITY(name) \
|
||||
DECLARE_FUNC_ENCODING \
|
||||
SYMBOL_NAME(name):
|
||||
|
||||
#define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \
|
||||
DEFINE_CODE_STATE \
|
||||
FILE_LEVEL_DIRECTIVE SEPARATOR \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
|
||||
DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \
|
||||
.thumb_func SEPARATOR \
|
||||
SYMBOL_NAME(name):
|
||||
|
||||
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \
|
||||
DEFINE_CODE_STATE \
|
||||
FILE_LEVEL_DIRECTIVE SEPARATOR \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
|
||||
HIDDEN(SYMBOL_NAME(name)) SEPARATOR \
|
||||
DECLARE_FUNC_ENCODING \
|
||||
SYMBOL_NAME(name):
|
||||
|
||||
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
|
||||
DEFINE_CODE_STATE \
|
||||
.globl name SEPARATOR \
|
||||
SYMBOL_IS_FUNC(name) SEPARATOR \
|
||||
HIDDEN(name) SEPARATOR \
|
||||
DECLARE_FUNC_ENCODING \
|
||||
name:
|
||||
|
||||
#define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
|
||||
DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR \
|
||||
.set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \
|
||||
DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name)
|
||||
#else
|
||||
#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)
|
||||
#endif
|
||||
|
||||
#ifdef __ELF__
|
||||
#define END_COMPILERRT_FUNCTION(name) \
|
||||
.size SYMBOL_NAME(name), . - SYMBOL_NAME(name)
|
||||
#else
|
||||
#define END_COMPILERRT_FUNCTION(name)
|
||||
#endif
|
||||
|
||||
#endif /* COMPILERRT_ASSEMBLY_H */
|
30
third_party/compiler_rt/bswapdi2.c
vendored
Normal file
30
third_party/compiler_rt/bswapdi2.c
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* clang-format off */
|
||||
/* ===-- bswapdi2.c - Implement __bswapdi2 ---------------------------------===
|
||||
*
|
||||
* 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 __bswapdi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
COMPILER_RT_ABI uint64_t __bswapdi2(uint64_t u) {
|
||||
return (
|
||||
(((u)&0xff00000000000000ULL) >> 56) |
|
||||
(((u)&0x00ff000000000000ULL) >> 40) |
|
||||
(((u)&0x0000ff0000000000ULL) >> 24) |
|
||||
(((u)&0x000000ff00000000ULL) >> 8) |
|
||||
(((u)&0x00000000ff000000ULL) << 8) |
|
||||
(((u)&0x0000000000ff0000ULL) << 24) |
|
||||
(((u)&0x000000000000ff00ULL) << 40) |
|
||||
(((u)&0x00000000000000ffULL) << 56));
|
||||
}
|
26
third_party/compiler_rt/bswapsi2.c
vendored
Normal file
26
third_party/compiler_rt/bswapsi2.c
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* clang-format off */
|
||||
/* ===-- bswapsi2.c - Implement __bswapsi2 ---------------------------------===
|
||||
*
|
||||
* 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 __bswapsi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
COMPILER_RT_ABI uint32_t __bswapsi2(uint32_t u) {
|
||||
return (
|
||||
(((u)&0xff000000) >> 24) |
|
||||
(((u)&0x00ff0000) >> 8) |
|
||||
(((u)&0x0000ff00) << 8) |
|
||||
(((u)&0x000000ff) << 24));
|
||||
}
|
183
third_party/compiler_rt/clear_cache.c
vendored
Normal file
183
third_party/compiler_rt/clear_cache.c
vendored
Normal file
|
@ -0,0 +1,183 @@
|
|||
/* clang-format off */
|
||||
/* ===-- clear_cache.c - Implement __clear_cache ---------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#if __APPLE__
|
||||
#include <libkern/OSCacheControl.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* Forward declare Win32 APIs since the GCC mode driver does not handle the
|
||||
newer SDKs as well as needed. */
|
||||
uint32_t FlushInstructionCache(uintptr_t hProcess, void *lpBaseAddress,
|
||||
uintptr_t dwSize);
|
||||
uintptr_t GetCurrentProcess(void);
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(__mips__)
|
||||
#if defined(__ANDROID__) && defined(__LP64__)
|
||||
/*
|
||||
* clear_mips_cache - Invalidates instruction cache for Mips.
|
||||
*/
|
||||
static void clear_mips_cache(const void* Addr, size_t Size) {
|
||||
__asm__ volatile (
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
".set noat\n"
|
||||
"beq %[Size], $zero, 20f\n" /* If size == 0, branch around. */
|
||||
"nop\n"
|
||||
"daddu %[Size], %[Addr], %[Size]\n" /* Calculate end address + 1 */
|
||||
"rdhwr $v0, $1\n" /* Get step size for SYNCI.
|
||||
$1 is $HW_SYNCI_Step */
|
||||
"beq $v0, $zero, 20f\n" /* If no caches require
|
||||
synchronization, branch
|
||||
around. */
|
||||
"nop\n"
|
||||
"10:\n"
|
||||
"synci 0(%[Addr])\n" /* Synchronize all caches around
|
||||
address. */
|
||||
"daddu %[Addr], %[Addr], $v0\n" /* Add step size. */
|
||||
"sltu $at, %[Addr], %[Size]\n" /* Compare current with end
|
||||
address. */
|
||||
"bne $at, $zero, 10b\n" /* Branch if more to do. */
|
||||
"nop\n"
|
||||
"sync\n" /* Clear memory hazards. */
|
||||
"20:\n"
|
||||
"bal 30f\n"
|
||||
"nop\n"
|
||||
"30:\n"
|
||||
"daddiu $ra, $ra, 12\n" /* $ra has a value of $pc here.
|
||||
Add offset of 12 to point to the
|
||||
instruction after the last nop.
|
||||
*/
|
||||
"jr.hb $ra\n" /* Return, clearing instruction
|
||||
hazards. */
|
||||
"nop\n"
|
||||
".set pop\n"
|
||||
: [Addr] "+r"(Addr), [Size] "+r"(Size)
|
||||
:: "at", "ra", "v0", "memory"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The compiler generates calls to __clear_cache() when creating
|
||||
* trampoline functions on the stack for use with nested functions.
|
||||
* It is expected to invalidate the instruction cache for the
|
||||
* specified range.
|
||||
*/
|
||||
|
||||
void __clear_cache(void *start, void *end) {
|
||||
#if __i386__ || __x86_64__ || defined(_M_IX86) || defined(_M_X64)
|
||||
/*
|
||||
* Intel processors have a unified instruction and data cache
|
||||
* so there is nothing to do
|
||||
*/
|
||||
#elif defined(_WIN32) && (defined(__arm__) || defined(__aarch64__))
|
||||
FlushInstructionCache(GetCurrentProcess(), start, end - start);
|
||||
#elif defined(__arm__) && !defined(__APPLE__)
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
struct arm_sync_icache_args arg;
|
||||
|
||||
arg.addr = (uintptr_t)start;
|
||||
arg.len = (uintptr_t)end - (uintptr_t)start;
|
||||
|
||||
sysarch(ARM_SYNC_ICACHE, &arg);
|
||||
#elif defined(__linux__)
|
||||
/*
|
||||
* We used to include asm/unistd.h for the __ARM_NR_cacheflush define, but
|
||||
* it also brought many other unused defines, as well as a dependency on
|
||||
* kernel headers to be installed.
|
||||
*
|
||||
* This value is stable at least since Linux 3.13 and should remain so for
|
||||
* compatibility reasons, warranting it's re-definition here.
|
||||
*/
|
||||
#define __ARM_NR_cacheflush 0x0f0002
|
||||
register int start_reg __asm("r0") = (int) (intptr_t) start;
|
||||
const register int end_reg __asm("r1") = (int) (intptr_t) end;
|
||||
const register int flags __asm("r2") = 0;
|
||||
const register int syscall_nr __asm("r7") = __ARM_NR_cacheflush;
|
||||
__asm __volatile("svc 0x0"
|
||||
: "=r"(start_reg)
|
||||
: "r"(syscall_nr), "r"(start_reg), "r"(end_reg),
|
||||
"r"(flags));
|
||||
assert(start_reg == 0 && "Cache flush syscall failed.");
|
||||
#else
|
||||
compilerrt_abort();
|
||||
#endif
|
||||
#elif defined(__linux__) && defined(__mips__)
|
||||
const uintptr_t start_int = (uintptr_t) start;
|
||||
const uintptr_t end_int = (uintptr_t) end;
|
||||
#if defined(__ANDROID__) && defined(__LP64__)
|
||||
// Call synci implementation for short address range.
|
||||
const uintptr_t address_range_limit = 256;
|
||||
if ((end_int - start_int) <= address_range_limit) {
|
||||
clear_mips_cache(start, (end_int - start_int));
|
||||
} else {
|
||||
syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE);
|
||||
}
|
||||
#else
|
||||
syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE);
|
||||
#endif
|
||||
#elif defined(__mips__) && defined(__OpenBSD__)
|
||||
cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE);
|
||||
#elif defined(__aarch64__) && !defined(__APPLE__)
|
||||
uint64_t xstart = (uint64_t)(uintptr_t) start;
|
||||
uint64_t xend = (uint64_t)(uintptr_t) end;
|
||||
uint64_t addr;
|
||||
|
||||
// Get Cache Type Info
|
||||
uint64_t ctr_el0;
|
||||
__asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0));
|
||||
|
||||
/*
|
||||
* dc & ic instructions must use 64bit registers so we don't use
|
||||
* uintptr_t in case this runs in an IPL32 environment.
|
||||
*/
|
||||
const size_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15);
|
||||
for (addr = xstart & ~(dcache_line_size - 1); addr < xend;
|
||||
addr += dcache_line_size)
|
||||
__asm __volatile("dc cvau, %0" :: "r"(addr));
|
||||
__asm __volatile("dsb ish");
|
||||
|
||||
const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15);
|
||||
for (addr = xstart & ~(icache_line_size - 1); addr < xend;
|
||||
addr += icache_line_size)
|
||||
__asm __volatile("ic ivau, %0" :: "r"(addr));
|
||||
__asm __volatile("isb sy");
|
||||
#elif defined (__powerpc64__)
|
||||
const size_t line_size = 32;
|
||||
const size_t len = (uintptr_t)end - (uintptr_t)start;
|
||||
|
||||
const uintptr_t mask = ~(line_size - 1);
|
||||
const uintptr_t start_line = ((uintptr_t)start) & mask;
|
||||
const uintptr_t end_line = ((uintptr_t)start + len + line_size - 1) & mask;
|
||||
|
||||
for (uintptr_t line = start_line; line < end_line; line += line_size)
|
||||
__asm__ volatile("dcbf 0, %0" : : "r"(line));
|
||||
__asm__ volatile("sync");
|
||||
|
||||
for (uintptr_t line = start_line; line < end_line; line += line_size)
|
||||
__asm__ volatile("icbi 0, %0" : : "r"(line));
|
||||
__asm__ volatile("isync");
|
||||
#else
|
||||
#if __APPLE__
|
||||
/* On Darwin, sys_icache_invalidate() provides this functionality */
|
||||
sys_icache_invalidate(start, end-start);
|
||||
#else
|
||||
compilerrt_abort();
|
||||
#endif
|
||||
#endif
|
||||
}
|
43
third_party/compiler_rt/clzdi2.c
vendored
Normal file
43
third_party/compiler_rt/clzdi2.c
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* clang-format off */
|
||||
/* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------===
|
||||
*
|
||||
* 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 __clzdi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: the number of leading 0-bits */
|
||||
|
||||
#if !defined(__clang__) && \
|
||||
((defined(__sparc__) && defined(__arch64__)) || \
|
||||
defined(__mips64) || \
|
||||
(defined(__riscv) && __SIZEOF_POINTER__ >= 8))
|
||||
/* On 64-bit architectures with neither a native clz instruction nor a native
|
||||
* ctz instruction, gcc resolves __builtin_clz to __clzdi2 rather than
|
||||
* __clzsi2, leading to infinite recursion. */
|
||||
#define __builtin_clz(a) __clzsi2(a)
|
||||
extern si_int __clzsi2(si_int);
|
||||
#endif
|
||||
|
||||
/* Precondition: a != 0 */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__clzdi2(di_int a)
|
||||
{
|
||||
dwords x;
|
||||
x.all = a;
|
||||
const si_int f = -(x.s.high == 0);
|
||||
return __builtin_clz((x.s.high & ~f) | (x.s.low & f)) +
|
||||
(f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
|
||||
}
|
56
third_party/compiler_rt/clzsi2.c
vendored
Normal file
56
third_party/compiler_rt/clzsi2.c
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* clang-format off */
|
||||
/* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------===
|
||||
*
|
||||
* 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 __clzsi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: the number of leading 0-bits */
|
||||
|
||||
/* Precondition: a != 0 */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__clzsi2(si_int a)
|
||||
{
|
||||
su_int x = (su_int)a;
|
||||
si_int t = ((x & 0xFFFF0000) == 0) << 4; /* if (x is small) t = 16 else 0 */
|
||||
x >>= 16 - t; /* x = [0 - 0xFFFF] */
|
||||
su_int r = t; /* r = [0, 16] */
|
||||
/* return r + clz(x) */
|
||||
t = ((x & 0xFF00) == 0) << 3;
|
||||
x >>= 8 - t; /* x = [0 - 0xFF] */
|
||||
r += t; /* r = [0, 8, 16, 24] */
|
||||
/* return r + clz(x) */
|
||||
t = ((x & 0xF0) == 0) << 2;
|
||||
x >>= 4 - t; /* x = [0 - 0xF] */
|
||||
r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */
|
||||
/* return r + clz(x) */
|
||||
t = ((x & 0xC) == 0) << 1;
|
||||
x >>= 2 - t; /* x = [0 - 3] */
|
||||
r += t; /* r = [0 - 30] and is even */
|
||||
/* return r + clz(x) */
|
||||
/* switch (x)
|
||||
* {
|
||||
* case 0:
|
||||
* return r + 2;
|
||||
* case 1:
|
||||
* return r + 1;
|
||||
* case 2:
|
||||
* case 3:
|
||||
* return r;
|
||||
* }
|
||||
*/
|
||||
return r + ((2 - x) & -((x & 2) == 0));
|
||||
}
|
36
third_party/compiler_rt/clzti2.c
vendored
Normal file
36
third_party/compiler_rt/clzti2.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* clang-format off */
|
||||
/* ===-- clzti2.c - Implement __clzti2 -------------------------------------===
|
||||
*
|
||||
* 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 __clzti2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: the number of leading 0-bits */
|
||||
|
||||
/* Precondition: a != 0 */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__clzti2(ti_int a)
|
||||
{
|
||||
twords x;
|
||||
x.all = a;
|
||||
const di_int f = -(x.s.high == 0);
|
||||
return __builtin_clzll((x.s.high & ~f) | (x.s.low & f)) +
|
||||
((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
54
third_party/compiler_rt/cmpdi2.c
vendored
Normal file
54
third_party/compiler_rt/cmpdi2.c
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* clang-format off */
|
||||
/* ===-- cmpdi2.c - Implement __cmpdi2 -------------------------------------===
|
||||
*
|
||||
* 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 __cmpdi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: if (a < b) returns 0
|
||||
* if (a == b) returns 1
|
||||
* if (a > b) returns 2
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__cmpdi2(di_int a, di_int b)
|
||||
{
|
||||
dwords x;
|
||||
x.all = a;
|
||||
dwords y;
|
||||
y.all = b;
|
||||
if (x.s.high < y.s.high)
|
||||
return 0;
|
||||
if (x.s.high > y.s.high)
|
||||
return 2;
|
||||
if (x.s.low < y.s.low)
|
||||
return 0;
|
||||
if (x.s.low > y.s.low)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __ARM_EABI__
|
||||
/* Returns: if (a < b) returns -1
|
||||
* if (a == b) returns 0
|
||||
* if (a > b) returns 1
|
||||
*/
|
||||
COMPILER_RT_ABI si_int
|
||||
__aeabi_lcmp(di_int a, di_int b)
|
||||
{
|
||||
return __cmpdi2(a, b) - 1;
|
||||
}
|
||||
#endif
|
||||
|
45
third_party/compiler_rt/cmpti2.c
vendored
Normal file
45
third_party/compiler_rt/cmpti2.c
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* clang-format off */
|
||||
/* ===-- cmpti2.c - Implement __cmpti2 -------------------------------------===
|
||||
*
|
||||
* 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 __cmpti2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: if (a < b) returns 0
|
||||
* if (a == b) returns 1
|
||||
* if (a > b) returns 2
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__cmpti2(ti_int a, ti_int b)
|
||||
{
|
||||
twords x;
|
||||
x.all = a;
|
||||
twords y;
|
||||
y.all = b;
|
||||
if (x.s.high < y.s.high)
|
||||
return 0;
|
||||
if (x.s.high > y.s.high)
|
||||
return 2;
|
||||
if (x.s.low < y.s.low)
|
||||
return 0;
|
||||
if (x.s.low > y.s.low)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
156
third_party/compiler_rt/comparedf2.c
vendored
Normal file
156
third_party/compiler_rt/comparedf2.c
vendored
Normal file
|
@ -0,0 +1,156 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/comparedf2.c - Double-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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// // This file implements the following soft-float comparison routines:
|
||||
//
|
||||
// __eqdf2 __gedf2 __unorddf2
|
||||
// __ledf2 __gtdf2
|
||||
// __ltdf2
|
||||
// __nedf2
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
// __ledf2(a,b) returns -1 if a < b
|
||||
// 0 if a == b
|
||||
// 1 if a > b
|
||||
// 1 if either a or b is NaN
|
||||
//
|
||||
// __gedf2(a,b) returns -1 if a < b
|
||||
// 0 if a == b
|
||||
// 1 if a > b
|
||||
// -1 if either a or b is NaN
|
||||
//
|
||||
// __unorddf2(a,b) returns 0 if both a and b are numbers
|
||||
// 1 if either a or b is NaN
|
||||
//
|
||||
// Note that __ledf2( ) and __gedf2( ) are identical except in their handling of
|
||||
// NaN values.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
enum LE_RESULT {
|
||||
LE_LESS = -1,
|
||||
LE_EQUAL = 0,
|
||||
LE_GREATER = 1,
|
||||
LE_UNORDERED = 1
|
||||
};
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT
|
||||
__ledf2(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 floating-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
|
||||
FNALIAS(__cmpdf2, __ledf2);
|
||||
#endif
|
||||
|
||||
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
|
||||
__gedf2(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_ABI int
|
||||
__unorddf2(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 preceding routines.
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT
|
||||
__eqdf2(fp_t a, fp_t b) {
|
||||
return __ledf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT
|
||||
__ltdf2(fp_t a, fp_t b) {
|
||||
return __ledf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT
|
||||
__nedf2(fp_t a, fp_t b) {
|
||||
return __ledf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum GE_RESULT
|
||||
__gtdf2(fp_t a, fp_t b) {
|
||||
return __gedf2(a, b);
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI int __aeabi_dcmpun(fp_t a, fp_t b) {
|
||||
return __unorddf2(a, b);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI int __aeabi_dcmpun(fp_t a, fp_t b) COMPILER_RT_ALIAS(__unorddf2);
|
||||
#endif
|
||||
#endif
|
156
third_party/compiler_rt/comparesf2.c
vendored
Normal file
156
third_party/compiler_rt/comparesf2.c
vendored
Normal file
|
@ -0,0 +1,156 @@
|
|||
/* clang-format off */
|
||||
//===-- 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
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
|
||||
FNALIAS(__cmpsf2, __lesf2);
|
||||
#endif
|
||||
|
||||
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_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 preceding routines.
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT
|
||||
__eqsf2(fp_t a, fp_t b) {
|
||||
return __lesf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT
|
||||
__ltsf2(fp_t a, fp_t b) {
|
||||
return __lesf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT
|
||||
__nesf2(fp_t a, fp_t b) {
|
||||
return __lesf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum GE_RESULT
|
||||
__gtsf2(fp_t a, fp_t b) {
|
||||
return __gesf2(a, b);
|
||||
}
|
||||
|
||||
#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
|
||||
AEABI_RTABI int __aeabi_fcmpun(fp_t a, fp_t b) COMPILER_RT_ALIAS(__unordsf2);
|
||||
#endif
|
||||
#endif
|
141
third_party/compiler_rt/comparetf2.c
vendored
Normal file
141
third_party/compiler_rt/comparetf2.c
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/comparetf2.c - Quad-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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// // This file implements the following soft-float comparison routines:
|
||||
//
|
||||
// __eqtf2 __getf2 __unordtf2
|
||||
// __letf2 __gttf2
|
||||
// __lttf2
|
||||
// __netf2
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
// __letf2(a,b) returns -1 if a < b
|
||||
// 0 if a == b
|
||||
// 1 if a > b
|
||||
// 1 if either a or b is NaN
|
||||
//
|
||||
// __getf2(a,b) returns -1 if a < b
|
||||
// 0 if a == b
|
||||
// 1 if a > b
|
||||
// -1 if either a or b is NaN
|
||||
//
|
||||
// __unordtf2(a,b) returns 0 if both a and b are numbers
|
||||
// 1 if either a or b is NaN
|
||||
//
|
||||
// Note that __letf2( ) and __getf2( ) are identical except in their handling of
|
||||
// NaN values.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
enum LE_RESULT {
|
||||
LE_LESS = -1,
|
||||
LE_EQUAL = 0,
|
||||
LE_GREATER = 1,
|
||||
LE_UNORDERED = 1
|
||||
};
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT __letf2(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 floating-point compare.
|
||||
if ((aInt & bInt) >= 0) {
|
||||
if (aInt < bInt) return LE_LESS;
|
||||
else if (aInt == bInt) return LE_EQUAL;
|
||||
else return LE_GREATER;
|
||||
}
|
||||
else {
|
||||
// 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).
|
||||
if (aInt > bInt) return LE_LESS;
|
||||
else if (aInt == bInt) return LE_EQUAL;
|
||||
else return LE_GREATER;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__ELF__)
|
||||
// Alias for libgcc compatibility
|
||||
FNALIAS(__cmptf2, __letf2);
|
||||
#endif
|
||||
|
||||
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 __getf2(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_ABI int __unordtf2(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 preceding routines.
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT __eqtf2(fp_t a, fp_t b) {
|
||||
return __letf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT __lttf2(fp_t a, fp_t b) {
|
||||
return __letf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum LE_RESULT __netf2(fp_t a, fp_t b) {
|
||||
return __letf2(a, b);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI enum GE_RESULT __gttf2(fp_t a, fp_t b) {
|
||||
return __getf2(a, b);
|
||||
}
|
||||
|
||||
#endif
|
60
third_party/compiler_rt/compiler_rt.mk
vendored
Normal file
60
third_party/compiler_rt/compiler_rt.mk
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += THIRD_PARTY_COMPILER_RT
|
||||
|
||||
THIRD_PARTY_COMPILER_RT_ARTIFACTS += THIRD_PARTY_COMPILER_RT_A
|
||||
THIRD_PARTY_COMPILER_RT = $(THIRD_PARTY_COMPILER_RT_A_DEPS) $(THIRD_PARTY_COMPILER_RT_A)
|
||||
THIRD_PARTY_COMPILER_RT_A = o/$(MODE)/third_party/compiler_rt/compiler_rt.a
|
||||
THIRD_PARTY_COMPILER_RT_A_FILES := \
|
||||
$(wildcard third_party/compiler_rt/*) \
|
||||
$(wildcard third_party/compiler_rt/nexgen32e/*)
|
||||
THIRD_PARTY_COMPILER_RT_A_HDRS = $(filter %.h,$(THIRD_PARTY_COMPILER_RT_A_FILES))
|
||||
THIRD_PARTY_COMPILER_RT_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_COMPILER_RT_A_FILES))
|
||||
THIRD_PARTY_COMPILER_RT_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_COMPILER_RT_A_FILES))
|
||||
|
||||
THIRD_PARTY_COMPILER_RT_A_SRCS = \
|
||||
$(THIRD_PARTY_COMPILER_RT_A_SRCS_S) \
|
||||
$(THIRD_PARTY_COMPILER_RT_A_SRCS_C)
|
||||
|
||||
THIRD_PARTY_COMPILER_RT_A_OBJS = \
|
||||
$(THIRD_PARTY_COMPILER_RT_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(THIRD_PARTY_COMPILER_RT_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(THIRD_PARTY_COMPILER_RT_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
THIRD_PARTY_COMPILER_RT_A_CHECKS = \
|
||||
$(THIRD_PARTY_COMPILER_RT_A).pkg \
|
||||
$(THIRD_PARTY_COMPILER_RT_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
THIRD_PARTY_COMPILER_RT_A_DIRECTDEPS = \
|
||||
LIBC_MATH \
|
||||
LIBC_STUBS
|
||||
|
||||
THIRD_PARTY_COMPILER_RT_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(THIRD_PARTY_COMPILER_RT_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(THIRD_PARTY_COMPILER_RT_A): \
|
||||
third_party/compiler_rt/ \
|
||||
$(THIRD_PARTY_COMPILER_RT_A).pkg \
|
||||
$(THIRD_PARTY_COMPILER_RT_A_OBJS)
|
||||
|
||||
$(THIRD_PARTY_COMPILER_RT_A).pkg: \
|
||||
$(THIRD_PARTY_COMPILER_RT_A_OBJS) \
|
||||
$(foreach x,$(THIRD_PARTY_COMPILER_RT_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
$(THIRD_PARTY_COMPILER_RT_A_OBJS): \
|
||||
DEFAULT_COPTS += \
|
||||
-DCRT_HAS_128BIT
|
||||
|
||||
o/$(MODE)/third_party/compiler_rt/multc3.o \
|
||||
o/$(MODE)/third_party/compiler_rt/divtc3.o: \
|
||||
DEFAULT_COPTS += \
|
||||
-w
|
||||
|
||||
THIRD_PARTY_COMPILER_RT_LIBS = $(foreach x,$(THIRD_PARTY_COMPILER_RT_ARTIFACTS),$($(x)))
|
||||
THIRD_PARTY_COMPILER_RT_SRCS = $(foreach x,$(THIRD_PARTY_COMPILER_RT_ARTIFACTS),$($(x)_SRCS))
|
||||
THIRD_PARTY_COMPILER_RT_CHECKS = $(foreach x,$(THIRD_PARTY_COMPILER_RT_ARTIFACTS),$($(x)_CHECKS))
|
||||
THIRD_PARTY_COMPILER_RT_OBJS = $(foreach x,$(THIRD_PARTY_COMPILER_RT_ARTIFACTS),$($(x)_OBJS))
|
||||
|
||||
.PHONY: o/$(MODE)/third_party/compiler_rt
|
||||
o/$(MODE)/third_party/compiler_rt: $(THIRD_PARTY_COMPILER_RT_CHECKS)
|
50
third_party/compiler_rt/comprt.S
vendored
Normal file
50
third_party/compiler_rt/comprt.S
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include "libc/macros.h"
|
||||
|
||||
/ Nop ref this to force pull the license into linkage.
|
||||
.section .yoink
|
||||
huge_compiler_rt_license:
|
||||
int3
|
||||
.endobj huge_compiler_rt_license,globl,hidden
|
||||
.previous
|
||||
|
||||
.ident "\n
|
||||
compiler_rt (Licensed MIT)
|
||||
Copyright (c) 2009-2015 by the contributors listed in:
|
||||
github.com/llvm-mirror/compiler-rt/blob/master/CREDITS.TXT"
|
||||
|
||||
.ident "\n
|
||||
compiler_rt (Licensed \"University of Illinois/NCSA Open Source License\")
|
||||
Copyright (c) 2009-2018 by the contributors listed in:
|
||||
github.com/llvm-mirror/compiler-rt/blob/master/CREDITS.TXT
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
University of Illinois at Urbana-Champaign
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the \"Software\"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the names of the LLVM Team, University of Illinois at
|
||||
Urbana-Champaign, nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this Software without specific
|
||||
prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE."
|
43
third_party/compiler_rt/ctzdi2.c
vendored
Normal file
43
third_party/compiler_rt/ctzdi2.c
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* clang-format off */
|
||||
/* ===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------===
|
||||
*
|
||||
* 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 __ctzdi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: the number of trailing 0-bits */
|
||||
|
||||
#if !defined(__clang__) && \
|
||||
((defined(__sparc__) && defined(__arch64__)) || \
|
||||
defined(__mips64) || \
|
||||
(defined(__riscv) && __SIZEOF_POINTER__ >= 8))
|
||||
/* On 64-bit architectures with neither a native clz instruction nor a native
|
||||
* ctz instruction, gcc resolves __builtin_ctz to __ctzdi2 rather than
|
||||
* __ctzsi2, leading to infinite recursion. */
|
||||
#define __builtin_ctz(a) __ctzsi2(a)
|
||||
extern si_int __ctzsi2(si_int);
|
||||
#endif
|
||||
|
||||
/* Precondition: a != 0 */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__ctzdi2(di_int a)
|
||||
{
|
||||
dwords x;
|
||||
x.all = a;
|
||||
const si_int f = -(x.s.low == 0);
|
||||
return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) +
|
||||
(f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
|
||||
}
|
60
third_party/compiler_rt/ctzsi2.c
vendored
Normal file
60
third_party/compiler_rt/ctzsi2.c
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* clang-format off */
|
||||
/* ===-- ctzsi2.c - Implement __ctzsi2 -------------------------------------===
|
||||
*
|
||||
* 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 __ctzsi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: the number of trailing 0-bits */
|
||||
|
||||
/* Precondition: a != 0 */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__ctzsi2(si_int a)
|
||||
{
|
||||
su_int x = (su_int)a;
|
||||
si_int t = ((x & 0x0000FFFF) == 0) << 4; /* if (x has no small bits) t = 16 else 0 */
|
||||
x >>= t; /* x = [0 - 0xFFFF] + higher garbage bits */
|
||||
su_int r = t; /* r = [0, 16] */
|
||||
/* return r + ctz(x) */
|
||||
t = ((x & 0x00FF) == 0) << 3;
|
||||
x >>= t; /* x = [0 - 0xFF] + higher garbage bits */
|
||||
r += t; /* r = [0, 8, 16, 24] */
|
||||
/* return r + ctz(x) */
|
||||
t = ((x & 0x0F) == 0) << 2;
|
||||
x >>= t; /* x = [0 - 0xF] + higher garbage bits */
|
||||
r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */
|
||||
/* return r + ctz(x) */
|
||||
t = ((x & 0x3) == 0) << 1;
|
||||
x >>= t;
|
||||
x &= 3; /* x = [0 - 3] */
|
||||
r += t; /* r = [0 - 30] and is even */
|
||||
/* return r + ctz(x) */
|
||||
|
||||
/* The branch-less return statement below is equivalent
|
||||
* to the following switch statement:
|
||||
* switch (x)
|
||||
* {
|
||||
* case 0:
|
||||
* return r + 2;
|
||||
* case 2:
|
||||
* return r + 1;
|
||||
* case 1:
|
||||
* case 3:
|
||||
* return r;
|
||||
* }
|
||||
*/
|
||||
return r + ((2 - (x >> 1)) & -((x & 1) == 0));
|
||||
}
|
36
third_party/compiler_rt/ctzti2.c
vendored
Normal file
36
third_party/compiler_rt/ctzti2.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* clang-format off */
|
||||
/* ===-- ctzti2.c - Implement __ctzti2 -------------------------------------===
|
||||
*
|
||||
* 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 __ctzti2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: the number of trailing 0-bits */
|
||||
|
||||
/* Precondition: a != 0 */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__ctzti2(ti_int a)
|
||||
{
|
||||
twords x;
|
||||
x.all = a;
|
||||
const di_int f = -(x.s.low == 0);
|
||||
return __builtin_ctzll((x.s.high & f) | (x.s.low & ~f)) +
|
||||
((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
58
third_party/compiler_rt/divdc3.c
vendored
Normal file
58
third_party/compiler_rt/divdc3.c
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* clang-format off */
|
||||
/* ===-- divdc3.c - Implement __divdc3 -------------------------------------===
|
||||
*
|
||||
* 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 __divdc3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
#include "third_party/compiler_rt/int_math.h"
|
||||
|
||||
/* Returns: the quotient of (a + ib) / (c + id) */
|
||||
|
||||
COMPILER_RT_ABI Dcomplex __divdc3(double __a, double __b, double __c,
|
||||
double __d) {
|
||||
int __ilogbw = 0;
|
||||
double __logbw = __compiler_rt_logb(crt_fmax(crt_fabs(__c), crt_fabs(__d)));
|
||||
if (crt_isfinite(__logbw)) {
|
||||
__ilogbw = (int)__logbw;
|
||||
__c = crt_scalbn(__c, -__ilogbw);
|
||||
__d = crt_scalbn(__d, -__ilogbw);
|
||||
}
|
||||
double __denom = __c * __c + __d * __d;
|
||||
Dcomplex z;
|
||||
COMPLEX_REAL(z) = crt_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
|
||||
COMPLEX_IMAGINARY(z) =
|
||||
crt_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
|
||||
if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) {
|
||||
if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b))) {
|
||||
COMPLEX_REAL(z) = crt_copysign(CRT_INFINITY, __c) * __a;
|
||||
COMPLEX_IMAGINARY(z) = crt_copysign(CRT_INFINITY, __c) * __b;
|
||||
} else if ((crt_isinf(__a) || crt_isinf(__b)) && crt_isfinite(__c) &&
|
||||
crt_isfinite(__d)) {
|
||||
__a = crt_copysign(crt_isinf(__a) ? 1.0 : 0.0, __a);
|
||||
__b = crt_copysign(crt_isinf(__b) ? 1.0 : 0.0, __b);
|
||||
COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
|
||||
} else if (crt_isinf(__logbw) && __logbw > 0.0 && crt_isfinite(__a) &&
|
||||
crt_isfinite(__b)) {
|
||||
__c = crt_copysign(crt_isinf(__c) ? 1.0 : 0.0, __c);
|
||||
__d = crt_copysign(crt_isinf(__d) ? 1.0 : 0.0, __d);
|
||||
COMPLEX_REAL(z) = 0.0 * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d);
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
197
third_party/compiler_rt/divdf3.c
vendored
Normal file
197
third_party/compiler_rt/divdf3.c
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/divdf3.c - Double-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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements double-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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
COMPILER_RT_ABI fp_t
|
||||
__divdf3(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;
|
||||
|
||||
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 / 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.
|
||||
const uint32_t q31b = bSignificand >> 21;
|
||||
uint32_t recip32 = 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 correction32;
|
||||
correction32 = -((uint64_t)recip32 * q31b >> 32);
|
||||
recip32 = (uint64_t)recip32 * correction32 >> 31;
|
||||
correction32 = -((uint64_t)recip32 * q31b >> 32);
|
||||
recip32 = (uint64_t)recip32 * correction32 >> 31;
|
||||
correction32 = -((uint64_t)recip32 * q31b >> 32);
|
||||
recip32 = (uint64_t)recip32 * correction32 >> 31;
|
||||
|
||||
// recip32 might have overflowed to exactly zero in the preceding
|
||||
// computation if the high word of b is exactly 1.0. This would sabotage
|
||||
// the full-width final stage of the computation that follows, so we adjust
|
||||
// recip32 downward by one bit.
|
||||
recip32--;
|
||||
|
||||
// We need to perform one more iteration to get us to 56 binary digits;
|
||||
// The last iteration needs to happen with extra precision.
|
||||
const uint32_t q63blo = bSignificand << 11;
|
||||
uint64_t correction, reciprocal;
|
||||
correction = -((uint64_t)recip32*q31b + ((uint64_t)recip32*q63blo >> 32));
|
||||
uint32_t cHi = correction >> 32;
|
||||
uint32_t cLo = correction;
|
||||
reciprocal = (uint64_t)recip32*cHi + ((uint64_t)recip32*cLo >> 32);
|
||||
|
||||
// We already adjusted the 32-bit estimate, now we need to adjust the final
|
||||
// 64-bit reciprocal estimate downward to ensure that it is strictly smaller
|
||||
// than the infinitely precise exact reciprocal. Because the computation
|
||||
// of the Newton-Raphson step is truncating at every step, this adjustment
|
||||
// is small; most of the work is already done.
|
||||
reciprocal -= 2;
|
||||
|
||||
// The numerical reciprocal is accurate to within 2^-56, lies in the
|
||||
// interval [0.5, 1.0), and is strictly smaller than the true reciprocal
|
||||
// of b. Multiplying a by this reciprocal thus gives a numerical q = a/b
|
||||
// in Q53 with the following properties:
|
||||
//
|
||||
// 1. q < a/b
|
||||
// 2. q is in the interval [0.5, 2.0)
|
||||
// 3. the error in q is bounded away from 2^-53 (actually, we have a
|
||||
// couple of bits to spare, but this is all we need).
|
||||
|
||||
// We need a 64 x 64 multiply high to compute q, which isn't a basic
|
||||
// operation in C, so we need to be a little bit fussy.
|
||||
rep_t quotient, quotientLo;
|
||||
wideMultiply(aSignificand << 2, reciprocal, "ient, "ientLo);
|
||||
|
||||
// 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 << 53) - quotient * bSignificand;
|
||||
quotientExponent--;
|
||||
} else {
|
||||
quotient >>= 1;
|
||||
residual = (aSignificand << 52) - 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 {
|
||||
const bool 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
|
||||
const double result = fromRep(absResult | quotientSign);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI fp_t __aeabi_ddiv(fp_t a, fp_t b) {
|
||||
return __divdf3(a, b);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI fp_t __aeabi_ddiv(fp_t a, fp_t b) COMPILER_RT_ALIAS(__divdf3);
|
||||
#endif
|
||||
#endif
|
32
third_party/compiler_rt/divdi3.c
vendored
Normal file
32
third_party/compiler_rt/divdi3.c
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* clang-format off */
|
||||
/* ===-- divdi3.c - Implement __divdi3 -------------------------------------===
|
||||
*
|
||||
* 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 __divdi3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: a / b */
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__divdi3(di_int a, di_int b)
|
||||
{
|
||||
const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;
|
||||
di_int s_a = a >> bits_in_dword_m1; /* s_a = a < 0 ? -1 : 0 */
|
||||
di_int s_b = b >> bits_in_dword_m1; /* s_b = b < 0 ? -1 : 0 */
|
||||
a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
|
||||
b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
|
||||
s_a ^= s_b; /*sign of quotient */
|
||||
return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */
|
||||
}
|
28
third_party/compiler_rt/divmoddi4.c
vendored
Normal file
28
third_party/compiler_rt/divmoddi4.c
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* clang-format off */
|
||||
/*===-- divmoddi4.c - Implement __divmoddi4 --------------------------------===
|
||||
*
|
||||
* 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 __divmoddi4 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: a / b, *rem = a % b */
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__divmoddi4(di_int a, di_int b, di_int* rem)
|
||||
{
|
||||
di_int d = __divdi3(a,b);
|
||||
*rem = a - (d*b);
|
||||
return d;
|
||||
}
|
30
third_party/compiler_rt/divmodsi4.c
vendored
Normal file
30
third_party/compiler_rt/divmodsi4.c
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* clang-format off */
|
||||
/*===-- divmodsi4.c - Implement __divmodsi4 --------------------------------===
|
||||
*
|
||||
* 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 __divmodsi4 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: a / b, *rem = a % b */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__divmodsi4(si_int a, si_int b, si_int* rem)
|
||||
{
|
||||
si_int d = __divsi3(a,b);
|
||||
*rem = a - (d*b);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
66
third_party/compiler_rt/divsc3.c
vendored
Normal file
66
third_party/compiler_rt/divsc3.c
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* clang-format off */
|
||||
/*===-- divsc3.c - Implement __divsc3 -------------------------------------===
|
||||
*
|
||||
* 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 __divsc3 for the compiler_rt library.
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
#include "third_party/compiler_rt/int_math.h"
|
||||
|
||||
/* Returns: the quotient of (a + ib) / (c + id) */
|
||||
|
||||
COMPILER_RT_ABI Fcomplex
|
||||
__divsc3(float __a, float __b, float __c, float __d)
|
||||
{
|
||||
int __ilogbw = 0;
|
||||
float __logbw =
|
||||
__compiler_rt_logbf(crt_fmaxf(crt_fabsf(__c), crt_fabsf(__d)));
|
||||
if (crt_isfinite(__logbw))
|
||||
{
|
||||
__ilogbw = (int)__logbw;
|
||||
__c = crt_scalbnf(__c, -__ilogbw);
|
||||
__d = crt_scalbnf(__d, -__ilogbw);
|
||||
}
|
||||
float __denom = __c * __c + __d * __d;
|
||||
Fcomplex z;
|
||||
COMPLEX_REAL(z) = crt_scalbnf((__a * __c + __b * __d) / __denom, -__ilogbw);
|
||||
COMPLEX_IMAGINARY(z) = crt_scalbnf((__b * __c - __a * __d) / __denom, -__ilogbw);
|
||||
if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
|
||||
{
|
||||
if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b)))
|
||||
{
|
||||
COMPLEX_REAL(z) = crt_copysignf(CRT_INFINITY, __c) * __a;
|
||||
COMPLEX_IMAGINARY(z) = crt_copysignf(CRT_INFINITY, __c) * __b;
|
||||
}
|
||||
else if ((crt_isinf(__a) || crt_isinf(__b)) &&
|
||||
crt_isfinite(__c) && crt_isfinite(__d))
|
||||
{
|
||||
__a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a);
|
||||
__b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b);
|
||||
COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
|
||||
}
|
||||
else if (crt_isinf(__logbw) && __logbw > 0 &&
|
||||
crt_isfinite(__a) && crt_isfinite(__b))
|
||||
{
|
||||
__c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c);
|
||||
__d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d);
|
||||
COMPLEX_REAL(z) = 0 * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = 0 * (__b * __c - __a * __d);
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
181
third_party/compiler_rt/divsf3.c
vendored
Normal file
181
third_party/compiler_rt/divsf3.c
vendored
Normal file
|
@ -0,0 +1,181 @@
|
|||
/* clang-format off */
|
||||
//===-- 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
COMPILER_RT_ABI 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;
|
||||
|
||||
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 / 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 {
|
||||
const bool 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
|
||||
AEABI_RTABI fp_t __aeabi_fdiv(fp_t a, fp_t b) COMPILER_RT_ALIAS(__divsf3);
|
||||
#endif
|
||||
#endif
|
42
third_party/compiler_rt/divsi3.c
vendored
Normal file
42
third_party/compiler_rt/divsi3.c
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* clang-format off */
|
||||
/* ===-- divsi3.c - Implement __divsi3 -------------------------------------===
|
||||
*
|
||||
* 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 __divsi3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: a / b */
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__divsi3(si_int a, si_int b)
|
||||
{
|
||||
const int bits_in_word_m1 = (int)(sizeof(si_int) * CHAR_BIT) - 1;
|
||||
si_int s_a = a >> bits_in_word_m1; /* s_a = a < 0 ? -1 : 0 */
|
||||
si_int s_b = b >> bits_in_word_m1; /* s_b = b < 0 ? -1 : 0 */
|
||||
a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
|
||||
b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
|
||||
s_a ^= s_b; /* sign of quotient */
|
||||
/*
|
||||
* On CPUs without unsigned hardware division support,
|
||||
* this calls __udivsi3 (notice the cast to su_int).
|
||||
* On CPUs with unsigned hardware division support,
|
||||
* this uses the unsigned division instruction.
|
||||
*/
|
||||
return ((su_int)a/(su_int)b ^ s_a) - s_a; /* negate if s_a == -1 */
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
AEABI_RTABI si_int __aeabi_idiv(si_int a, si_int b) COMPILER_RT_ALIAS(__divsi3);
|
||||
#endif
|
66
third_party/compiler_rt/divtc3.c
vendored
Normal file
66
third_party/compiler_rt/divtc3.c
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* clang-format off */
|
||||
/*===-- divtc3.c - Implement __divtc3 -------------------------------------===
|
||||
*
|
||||
* 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 __divtc3 for the compiler_rt library.
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
#include "third_party/compiler_rt/int_math.h"
|
||||
|
||||
/* Returns: the quotient of (a + ib) / (c + id) */
|
||||
|
||||
COMPILER_RT_ABI Lcomplex
|
||||
__divtc3(long double __a, long double __b, long double __c, long double __d)
|
||||
{
|
||||
int __ilogbw = 0;
|
||||
long double __logbw =
|
||||
__compiler_rt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));
|
||||
if (crt_isfinite(__logbw))
|
||||
{
|
||||
__ilogbw = (int)__logbw;
|
||||
__c = crt_scalbnl(__c, -__ilogbw);
|
||||
__d = crt_scalbnl(__d, -__ilogbw);
|
||||
}
|
||||
long double __denom = __c * __c + __d * __d;
|
||||
Lcomplex z;
|
||||
COMPLEX_REAL(z) = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
|
||||
COMPLEX_IMAGINARY(z) = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);
|
||||
if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
|
||||
{
|
||||
if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b)))
|
||||
{
|
||||
COMPLEX_REAL(z) = crt_copysignl(CRT_INFINITY, __c) * __a;
|
||||
COMPLEX_IMAGINARY(z) = crt_copysignl(CRT_INFINITY, __c) * __b;
|
||||
}
|
||||
else if ((crt_isinf(__a) || crt_isinf(__b)) &&
|
||||
crt_isfinite(__c) && crt_isfinite(__d))
|
||||
{
|
||||
__a = crt_copysignl(crt_isinf(__a) ? 1.0 : 0.0, __a);
|
||||
__b = crt_copysignl(crt_isinf(__b) ? 1.0 : 0.0, __b);
|
||||
COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
|
||||
}
|
||||
else if (crt_isinf(__logbw) && __logbw > 0.0 &&
|
||||
crt_isfinite(__a) && crt_isfinite(__b))
|
||||
{
|
||||
__c = crt_copysignl(crt_isinf(__c) ? 1.0 : 0.0, __c);
|
||||
__d = crt_copysignl(crt_isinf(__d) ? 1.0 : 0.0, __d);
|
||||
COMPLEX_REAL(z) = 0.0 * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d);
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
207
third_party/compiler_rt/divtf3.c
vendored
Normal file
207
third_party/compiler_rt/divtf3.c
vendored
Normal file
|
@ -0,0 +1,207 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/divtf3.c - Quad-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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements quad-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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
COMPILER_RT_ABI fp_t __divtf3(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;
|
||||
|
||||
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 / 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 Q63 fixed-point number in the range
|
||||
// [1, 2.0) and get a Q64 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.
|
||||
const uint64_t q63b = bSignificand >> 49;
|
||||
uint64_t recip64 = UINT64_C(0x7504f333F9DE6484) - q63b;
|
||||
// 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2)
|
||||
|
||||
// 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.
|
||||
uint64_t correction64;
|
||||
correction64 = -((rep_t)recip64 * q63b >> 64);
|
||||
recip64 = (rep_t)recip64 * correction64 >> 63;
|
||||
correction64 = -((rep_t)recip64 * q63b >> 64);
|
||||
recip64 = (rep_t)recip64 * correction64 >> 63;
|
||||
correction64 = -((rep_t)recip64 * q63b >> 64);
|
||||
recip64 = (rep_t)recip64 * correction64 >> 63;
|
||||
correction64 = -((rep_t)recip64 * q63b >> 64);
|
||||
recip64 = (rep_t)recip64 * correction64 >> 63;
|
||||
correction64 = -((rep_t)recip64 * q63b >> 64);
|
||||
recip64 = (rep_t)recip64 * correction64 >> 63;
|
||||
|
||||
// recip64 might have overflowed to exactly zero in the preceeding
|
||||
// computation if the high word of b is exactly 1.0. This would sabotage
|
||||
// the full-width final stage of the computation that follows, so we adjust
|
||||
// recip64 downward by one bit.
|
||||
recip64--;
|
||||
|
||||
// We need to perform one more iteration to get us to 112 binary digits;
|
||||
// The last iteration needs to happen with extra precision.
|
||||
const uint64_t q127blo = bSignificand << 15;
|
||||
rep_t correction, reciprocal;
|
||||
|
||||
// NOTE: This operation is equivalent to __multi3, which is not implemented
|
||||
// in some architechure
|
||||
rep_t r64q63, r64q127, r64cH, r64cL, dummy;
|
||||
wideMultiply((rep_t)recip64, (rep_t)q63b, &dummy, &r64q63);
|
||||
wideMultiply((rep_t)recip64, (rep_t)q127blo, &dummy, &r64q127);
|
||||
|
||||
correction = -(r64q63 + (r64q127 >> 64));
|
||||
|
||||
uint64_t cHi = correction >> 64;
|
||||
uint64_t cLo = correction;
|
||||
|
||||
wideMultiply((rep_t)recip64, (rep_t)cHi, &dummy, &r64cH);
|
||||
wideMultiply((rep_t)recip64, (rep_t)cLo, &dummy, &r64cL);
|
||||
|
||||
reciprocal = r64cH + (r64cL >> 64);
|
||||
|
||||
// We already adjusted the 64-bit estimate, now we need to adjust the final
|
||||
// 128-bit reciprocal estimate downward to ensure that it is strictly smaller
|
||||
// than the infinitely precise exact reciprocal. Because the computation
|
||||
// of the Newton-Raphson step is truncating at every step, this adjustment
|
||||
// is small; most of the work is already done.
|
||||
reciprocal -= 2;
|
||||
|
||||
// The numerical reciprocal is accurate to within 2^-112, lies in the
|
||||
// interval [0.5, 1.0), and is strictly smaller than the true reciprocal
|
||||
// of b. Multiplying a by this reciprocal thus gives a numerical q = a/b
|
||||
// in Q127 with the following properties:
|
||||
//
|
||||
// 1. q < a/b
|
||||
// 2. q is in the interval [0.5, 2.0)
|
||||
// 3. the error in q is bounded away from 2^-113 (actually, we have a
|
||||
// couple of bits to spare, but this is all we need).
|
||||
|
||||
// We need a 128 x 128 multiply high to compute q, which isn't a basic
|
||||
// operation in C, so we need to be a little bit fussy.
|
||||
rep_t quotient, quotientLo;
|
||||
wideMultiply(aSignificand << 2, reciprocal, "ient, "ientLo);
|
||||
|
||||
// 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;
|
||||
rep_t qb;
|
||||
|
||||
if (quotient < (implicitBit << 1)) {
|
||||
wideMultiply(quotient, bSignificand, &dummy, &qb);
|
||||
residual = (aSignificand << 113) - qb;
|
||||
quotientExponent--;
|
||||
} else {
|
||||
quotient >>= 1;
|
||||
wideMultiply(quotient, bSignificand, &dummy, &qb);
|
||||
residual = (aSignificand << 112) - qb;
|
||||
}
|
||||
|
||||
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 {
|
||||
const bool 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
|
||||
const long double result = fromRep(absResult | quotientSign);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
36
third_party/compiler_rt/divti3.c
vendored
Normal file
36
third_party/compiler_rt/divti3.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* clang-format off */
|
||||
/* ===-- divti3.c - Implement __divti3 -------------------------------------===
|
||||
*
|
||||
* 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 __divti3 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: a / b */
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__divti3(ti_int a, ti_int b)
|
||||
{
|
||||
const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
|
||||
ti_int s_a = a >> bits_in_tword_m1; /* s_a = a < 0 ? -1 : 0 */
|
||||
ti_int s_b = b >> bits_in_tword_m1; /* s_b = b < 0 ? -1 : 0 */
|
||||
a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
|
||||
b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
|
||||
s_a ^= s_b; /* sign of quotient */
|
||||
return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
66
third_party/compiler_rt/divxc3.c
vendored
Normal file
66
third_party/compiler_rt/divxc3.c
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* clang-format off */
|
||||
/* ===-- divxc3.c - Implement __divxc3 -------------------------------------===
|
||||
*
|
||||
* 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 __divxc3 for the compiler_rt library.
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#if !_ARCH_PPC
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
#include "third_party/compiler_rt/int_math.h"
|
||||
|
||||
/* Returns: the quotient of (a + ib) / (c + id) */
|
||||
|
||||
COMPILER_RT_ABI Lcomplex
|
||||
__divxc3(long double __a, long double __b, long double __c, long double __d)
|
||||
{
|
||||
int __ilogbw = 0;
|
||||
long double __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));
|
||||
if (crt_isfinite(__logbw))
|
||||
{
|
||||
__ilogbw = (int)__logbw;
|
||||
__c = crt_scalbnl(__c, -__ilogbw);
|
||||
__d = crt_scalbnl(__d, -__ilogbw);
|
||||
}
|
||||
long double __denom = __c * __c + __d * __d;
|
||||
Lcomplex z;
|
||||
COMPLEX_REAL(z) = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
|
||||
COMPLEX_IMAGINARY(z) = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);
|
||||
if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
|
||||
{
|
||||
if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b)))
|
||||
{
|
||||
COMPLEX_REAL(z) = crt_copysignl(CRT_INFINITY, __c) * __a;
|
||||
COMPLEX_IMAGINARY(z) = crt_copysignl(CRT_INFINITY, __c) * __b;
|
||||
}
|
||||
else if ((crt_isinf(__a) || crt_isinf(__b)) &&
|
||||
crt_isfinite(__c) && crt_isfinite(__d))
|
||||
{
|
||||
__a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a);
|
||||
__b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b);
|
||||
COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
|
||||
}
|
||||
else if (crt_isinf(__logbw) && __logbw > 0 &&
|
||||
crt_isfinite(__a) && crt_isfinite(__b))
|
||||
{
|
||||
__c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c);
|
||||
__d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d);
|
||||
COMPLEX_REAL(z) = 0 * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = 0 * (__b * __c - __a * __d);
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif
|
26
third_party/compiler_rt/extenddftf2.c
vendored
Normal file
26
third_party/compiler_rt/extenddftf2.c
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/extenddftf2.c - double -> quad 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
#define SRC_DOUBLE
|
||||
#define DST_QUAD
|
||||
#include "third_party/compiler_rt/fp_extend_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI long double __extenddftf2(double a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
|
||||
#endif
|
36
third_party/compiler_rt/extendhfsf2.c
vendored
Normal file
36
third_party/compiler_rt/extendhfsf2.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/extendhfsf2.c - half -> single 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SRC_HALF
|
||||
#define DST_SINGLE
|
||||
#include "third_party/compiler_rt/fp_extend_impl.inc"
|
||||
|
||||
// Use a forwarding definition and noinline to implement a poor man's alias,
|
||||
// as there isn't a good cross-platform way of defining one.
|
||||
COMPILER_RT_ABI __attribute__((__noinline__)) float __extendhfsf2(uint16_t a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
|
||||
COMPILER_RT_ABI float __gnu_h2f_ieee(uint16_t a) {
|
||||
return __extendhfsf2(a);
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI float __aeabi_h2f(uint16_t a) {
|
||||
return __extendhfsf2(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI float __aeabi_h2f(uint16_t a) COMPILER_RT_ALIAS(__extendhfsf2);
|
||||
#endif
|
||||
#endif
|
30
third_party/compiler_rt/extendsfdf2.c
vendored
Normal file
30
third_party/compiler_rt/extendsfdf2.c
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/extendsfdf2.c - single -> double 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SRC_SINGLE
|
||||
#define DST_DOUBLE
|
||||
#include "third_party/compiler_rt/fp_extend_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI double __extendsfdf2(float a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI double __aeabi_f2d(float a) {
|
||||
return __extendsfdf2(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI double __aeabi_f2d(float a) COMPILER_RT_ALIAS(__extendsfdf2);
|
||||
#endif
|
||||
#endif
|
26
third_party/compiler_rt/extendsftf2.c
vendored
Normal file
26
third_party/compiler_rt/extendsftf2.c
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/extendsftf2.c - single -> quad 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
#define SRC_SINGLE
|
||||
#define DST_QUAD
|
||||
#include "third_party/compiler_rt/fp_extend_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI long double __extendsftf2(float a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
|
||||
#endif
|
36
third_party/compiler_rt/ffsdi2.c
vendored
Normal file
36
third_party/compiler_rt/ffsdi2.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* clang-format off */
|
||||
/* ===-- ffsdi2.c - Implement __ffsdi2 -------------------------------------===
|
||||
*
|
||||
* 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 __ffsdi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: the index of the least significant 1-bit in a, or
|
||||
* the value zero if a is zero. The least significant bit is index one.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__ffsdi2(di_int a)
|
||||
{
|
||||
dwords x;
|
||||
x.all = a;
|
||||
if (x.s.low == 0)
|
||||
{
|
||||
if (x.s.high == 0)
|
||||
return 0;
|
||||
return __builtin_ctz(x.s.high) + (1 + sizeof(si_int) * CHAR_BIT);
|
||||
}
|
||||
return __builtin_ctz(x.s.low) + 1;
|
||||
}
|
32
third_party/compiler_rt/ffssi2.c
vendored
Normal file
32
third_party/compiler_rt/ffssi2.c
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* clang-format off */
|
||||
/* ===-- ffssi2.c - Implement __ffssi2 -------------------------------------===
|
||||
*
|
||||
* 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 __ffssi2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: the index of the least significant 1-bit in a, or
|
||||
* the value zero if a is zero. The least significant bit is index one.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__ffssi2(si_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return __builtin_ctz(a) + 1;
|
||||
}
|
40
third_party/compiler_rt/ffsti2.c
vendored
Normal file
40
third_party/compiler_rt/ffsti2.c
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* clang-format off */
|
||||
/* ===-- ffsti2.c - Implement __ffsti2 -------------------------------------===
|
||||
*
|
||||
* 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 __ffsti2 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: the index of the least significant 1-bit in a, or
|
||||
* the value zero if a is zero. The least significant bit is index one.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__ffsti2(ti_int a)
|
||||
{
|
||||
twords x;
|
||||
x.all = a;
|
||||
if (x.s.low == 0)
|
||||
{
|
||||
if (x.s.high == 0)
|
||||
return 0;
|
||||
return __builtin_ctzll(x.s.high) + (1 + sizeof(di_int) * CHAR_BIT);
|
||||
}
|
||||
return __builtin_ctzll(x.s.low) + 1;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
58
third_party/compiler_rt/fixdfdi.c
vendored
Normal file
58
third_party/compiler_rt/fixdfdi.c
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixdfdi.c - Implement __fixdfdi -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#ifndef __SOFT_FP__
|
||||
/* Support for systems that have hardware floating-point; can set the invalid
|
||||
* flag as a side-effect of computation.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI du_int __fixunsdfdi(double a);
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixdfdi(double a)
|
||||
{
|
||||
if (a < 0.0) {
|
||||
return -__fixunsdfdi(-a);
|
||||
}
|
||||
return __fixunsdfdi(a);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Support for systems that don't have hardware floating-point; there are no
|
||||
* flags to set, and we don't want to code-gen to an unknown soft-float
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
typedef di_int fixint_t;
|
||||
typedef du_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixdfdi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI di_int __aeabi_d2lz(fp_t a) {
|
||||
return __fixdfdi(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI di_int __aeabi_d2lz(fp_t a) COMPILER_RT_ALIAS(__fixdfdi);
|
||||
#endif
|
||||
#endif
|
33
third_party/compiler_rt/fixdfsi.c
vendored
Normal file
33
third_party/compiler_rt/fixdfsi.c
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixdfsi.c - Implement __fixdfsi -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
typedef si_int fixint_t;
|
||||
typedef su_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__fixdfsi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI si_int __aeabi_d2iz(fp_t a) {
|
||||
return __fixdfsi(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI si_int __aeabi_d2iz(fp_t a) COMPILER_RT_ALIAS(__fixdfsi);
|
||||
#endif
|
||||
#endif
|
29
third_party/compiler_rt/fixdfti.c
vendored
Normal file
29
third_party/compiler_rt/fixdfti.c
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixdfti.c - Implement __fixdfti -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
typedef ti_int fixint_t;
|
||||
typedef tu_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__fixdfti(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
58
third_party/compiler_rt/fixsfdi.c
vendored
Normal file
58
third_party/compiler_rt/fixsfdi.c
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixsfdi.c - Implement __fixsfdi -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#ifndef __SOFT_FP__
|
||||
/* Support for systems that have hardware floating-point; can set the invalid
|
||||
* flag as a side-effect of computation.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI du_int __fixunssfdi(float a);
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixsfdi(float a)
|
||||
{
|
||||
if (a < 0.0f) {
|
||||
return -__fixunssfdi(-a);
|
||||
}
|
||||
return __fixunssfdi(a);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Support for systems that don't have hardware floating-point; there are no
|
||||
* flags to set, and we don't want to code-gen to an unknown soft-float
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
typedef di_int fixint_t;
|
||||
typedef du_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixsfdi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI di_int __aeabi_f2lz(fp_t a) {
|
||||
return __fixsfdi(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI di_int __aeabi_f2lz(fp_t a) COMPILER_RT_ALIAS(__fixsfdi);
|
||||
#endif
|
||||
#endif
|
33
third_party/compiler_rt/fixsfsi.c
vendored
Normal file
33
third_party/compiler_rt/fixsfsi.c
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* clang-format off */
|
||||
/* ===-- 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
typedef si_int fixint_t;
|
||||
typedef su_int fixuint_t;
|
||||
#include "third_party/compiler_rt/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
|
||||
AEABI_RTABI si_int __aeabi_f2iz(fp_t a) COMPILER_RT_ALIAS(__fixsfsi);
|
||||
#endif
|
||||
#endif
|
29
third_party/compiler_rt/fixsfti.c
vendored
Normal file
29
third_party/compiler_rt/fixsfti.c
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixsfti.c - Implement __fixsfti -----------------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
typedef ti_int fixint_t;
|
||||
typedef tu_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__fixsfti(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
26
third_party/compiler_rt/fixtfdi.c
vendored
Normal file
26
third_party/compiler_rt/fixtfdi.c
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixtfdi.c - Implement __fixtfdi -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef di_int fixint_t;
|
||||
typedef du_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixtfdi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
#endif
|
26
third_party/compiler_rt/fixtfsi.c
vendored
Normal file
26
third_party/compiler_rt/fixtfsi.c
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixtfsi.c - Implement __fixtfsi -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef si_int fixint_t;
|
||||
typedef su_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI si_int
|
||||
__fixtfsi(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
#endif
|
26
third_party/compiler_rt/fixtfti.c
vendored
Normal file
26
third_party/compiler_rt/fixtfti.c
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixtfti.c - Implement __fixtfti -----------------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef ti_int fixint_t;
|
||||
typedef tu_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__fixtfti(fp_t a) {
|
||||
return __fixint(a);
|
||||
}
|
||||
#endif
|
55
third_party/compiler_rt/fixunsdfdi.c
vendored
Normal file
55
third_party/compiler_rt/fixunsdfdi.c
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#ifndef __SOFT_FP__
|
||||
/* Support for systems that have hardware floating-point; can set the invalid
|
||||
* flag as a side-effect of computation.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunsdfdi(double a)
|
||||
{
|
||||
if (a <= 0.0) return 0;
|
||||
su_int high = a / 4294967296.f; /* a / 0x1p32f; */
|
||||
su_int low = a - (double)high * 4294967296.f; /* high * 0x1p32f; */
|
||||
return ((du_int)high << 32) | low;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Support for systems that don't have hardware floating-point; there are no
|
||||
* flags to set, and we don't want to code-gen to an unknown soft-float
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
typedef du_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunsdfdi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI du_int __aeabi_d2ulz(fp_t a) {
|
||||
return __fixunsdfdi(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI du_int __aeabi_d2ulz(fp_t a) COMPILER_RT_ALIAS(__fixunsdfdi);
|
||||
#endif
|
||||
#endif
|
32
third_party/compiler_rt/fixunsdfsi.c
vendored
Normal file
32
third_party/compiler_rt/fixunsdfsi.c
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
typedef su_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI su_int
|
||||
__fixunsdfsi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI su_int __aeabi_d2uiz(fp_t a) {
|
||||
return __fixunsdfsi(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI su_int __aeabi_d2uiz(fp_t a) COMPILER_RT_ALIAS(__fixunsdfsi);
|
||||
#endif
|
||||
#endif
|
26
third_party/compiler_rt/fixunsdfti.c
vendored
Normal file
26
third_party/compiler_rt/fixunsdfti.c
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunsdfti.c - Implement __fixunsdfti -----------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
typedef tu_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI tu_int
|
||||
__fixunsdfti(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
#endif /* CRT_HAS_128BIT */
|
56
third_party/compiler_rt/fixunssfdi.c
vendored
Normal file
56
third_party/compiler_rt/fixunssfdi.c
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunssfdi.c - Implement __fixunssfdi -----------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#ifndef __SOFT_FP__
|
||||
/* Support for systems that have hardware floating-point; can set the invalid
|
||||
* flag as a side-effect of computation.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunssfdi(float a)
|
||||
{
|
||||
if (a <= 0.0f) return 0;
|
||||
double da = a;
|
||||
su_int high = da / 4294967296.f; /* da / 0x1p32f; */
|
||||
su_int low = da - (double)high * 4294967296.f; /* high * 0x1p32f; */
|
||||
return ((du_int)high << 32) | low;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Support for systems that don't have hardware floating-point; there are no
|
||||
* flags to set, and we don't want to code-gen to an unknown soft-float
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
typedef du_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunssfdi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI du_int __aeabi_f2ulz(fp_t a) {
|
||||
return __fixunssfdi(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI du_int __aeabi_f2ulz(fp_t a) COMPILER_RT_ALIAS(__fixunssfdi);
|
||||
#endif
|
||||
#endif
|
36
third_party/compiler_rt/fixunssfsi.c
vendored
Normal file
36
third_party/compiler_rt/fixunssfsi.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* clang-format off */
|
||||
/* ===-- 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
typedef su_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI su_int
|
||||
__fixunssfsi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI su_int __aeabi_f2uiz(fp_t a) {
|
||||
return __fixunssfsi(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI su_int __aeabi_f2uiz(fp_t a) COMPILER_RT_ALIAS(__fixunssfsi);
|
||||
#endif
|
||||
#endif
|
29
third_party/compiler_rt/fixunssfti.c
vendored
Normal file
29
third_party/compiler_rt/fixunssfti.c
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunssfti.c - Implement __fixunssfti -----------------------------===
|
||||
*
|
||||
* 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 __fixunssfti for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT)
|
||||
typedef tu_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI tu_int
|
||||
__fixunssfti(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
#endif
|
25
third_party/compiler_rt/fixunstfdi.c
vendored
Normal file
25
third_party/compiler_rt/fixunstfdi.c
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunstfdi.c - Implement __fixunstfdi -----------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef du_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunstfdi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
#endif
|
25
third_party/compiler_rt/fixunstfsi.c
vendored
Normal file
25
third_party/compiler_rt/fixunstfsi.c
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef su_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI su_int
|
||||
__fixunstfsi(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
#endif
|
25
third_party/compiler_rt/fixunstfti.c
vendored
Normal file
25
third_party/compiler_rt/fixunstfti.c
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
typedef tu_int fixuint_t;
|
||||
#include "third_party/compiler_rt/fp_fixuint_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI tu_int
|
||||
__fixunstfti(fp_t a) {
|
||||
return __fixuint(a);
|
||||
}
|
||||
#endif
|
49
third_party/compiler_rt/fixunsxfdi.c
vendored
Normal file
49
third_party/compiler_rt/fixunsxfdi.c
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunsxfdi.c - Implement __fixunsxfdi -----------------------------===
|
||||
*
|
||||
* 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 __fixunsxfdi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#if !_ARCH_PPC
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: convert a to a unsigned long long, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* du_int is a 64 bit integral type
|
||||
* value in long double is representable in du_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__fixunsxfdi(long double a)
|
||||
{
|
||||
long_double_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
return 0;
|
||||
if ((unsigned)e > sizeof(du_int) * CHAR_BIT)
|
||||
return ~(du_int)0;
|
||||
return fb.u.low.all >> (63 - e);
|
||||
}
|
||||
|
||||
#endif
|
48
third_party/compiler_rt/fixunsxfsi.c
vendored
Normal file
48
third_party/compiler_rt/fixunsxfsi.c
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunsxfsi.c - Implement __fixunsxfsi -----------------------------===
|
||||
*
|
||||
* 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 __fixunsxfsi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#if !_ARCH_PPC
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: convert a to a unsigned int, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* su_int is a 32 bit integral type
|
||||
* value in long double is representable in su_int or is negative
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI su_int
|
||||
__fixunsxfsi(long double a)
|
||||
{
|
||||
long_double_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
return 0;
|
||||
if ((unsigned)e > sizeof(su_int) * CHAR_BIT)
|
||||
return ~(su_int)0;
|
||||
return fb.u.low.s.high >> (31 - e);
|
||||
}
|
||||
|
||||
#endif /* !_ARCH_PPC */
|
53
third_party/compiler_rt/fixunsxfti.c
vendored
Normal file
53
third_party/compiler_rt/fixunsxfti.c
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixunsxfti.c - Implement __fixunsxfti -----------------------------===
|
||||
*
|
||||
* 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 __fixunsxfti for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a unsigned long long, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* tu_int is a 128 bit integral type
|
||||
* value in long double is representable in tu_int or is negative
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI tu_int
|
||||
__fixunsxfti(long double a)
|
||||
{
|
||||
long_double_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
return 0;
|
||||
if ((unsigned)e > sizeof(tu_int) * CHAR_BIT)
|
||||
return ~(tu_int)0;
|
||||
tu_int r = fb.u.low.all;
|
||||
if (e > 63)
|
||||
r <<= (e - 63);
|
||||
else
|
||||
r >>= (63 - e);
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
51
third_party/compiler_rt/fixxfdi.c
vendored
Normal file
51
third_party/compiler_rt/fixxfdi.c
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixxfdi.c - Implement __fixxfdi -----------------------------------===
|
||||
*
|
||||
* 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 __fixxfdi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#if !_ARCH_PPC
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: convert a to a signed long long, rounding toward zero. */
|
||||
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* di_int is a 64 bit integral type
|
||||
* value in long double is representable in di_int (no range checking performed)
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI di_int
|
||||
__fixxfdi(long double a)
|
||||
{
|
||||
const di_int di_max = (di_int)((~(du_int)0) / 2);
|
||||
const di_int di_min = -di_max - 1;
|
||||
long_double_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0)
|
||||
return 0;
|
||||
if ((unsigned)e >= sizeof(di_int) * CHAR_BIT)
|
||||
return a > 0 ? di_max : di_min;
|
||||
di_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
|
||||
di_int r = fb.u.low.all;
|
||||
r = (du_int)r >> (63 - e);
|
||||
return (r ^ s) - s;
|
||||
}
|
||||
|
||||
#endif /* !_ARCH_PPC */
|
54
third_party/compiler_rt/fixxfti.c
vendored
Normal file
54
third_party/compiler_rt/fixxfti.c
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* clang-format off */
|
||||
/* ===-- fixxfti.c - Implement __fixxfti -----------------------------------===
|
||||
*
|
||||
* 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 __fixxfti for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a signed long long, rounding toward zero. */
|
||||
|
||||
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
|
||||
* ti_int is a 128 bit integral type
|
||||
* value in long double is representable in ti_int
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI ti_int
|
||||
__fixxfti(long double a)
|
||||
{
|
||||
const ti_int ti_max = (ti_int)((~(tu_int)0) / 2);
|
||||
const ti_int ti_min = -ti_max - 1;
|
||||
long_double_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0)
|
||||
return 0;
|
||||
ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
|
||||
ti_int r = fb.u.low.all;
|
||||
if ((unsigned)e >= sizeof(ti_int) * CHAR_BIT)
|
||||
return a > 0 ? ti_max : ti_min;
|
||||
if (e > 63)
|
||||
r <<= (e - 63);
|
||||
else
|
||||
r >>= (63 - e);
|
||||
return (r ^ s) - s;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
119
third_party/compiler_rt/floatdidf.c
vendored
Normal file
119
third_party/compiler_rt/floatdidf.c
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* clang-format off */
|
||||
/*===-- floatdidf.c - Implement __floatdidf -------------------------------===
|
||||
*
|
||||
* 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 __floatdidf for the compiler_rt library.
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: convert a to a double, rounding toward even. */
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* di_int is a 64 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
#ifndef __SOFT_FP__
|
||||
/* Support for systems that have hardware floating-point; we'll set the inexact flag
|
||||
* as a side-effect of this computation.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI double
|
||||
__floatdidf(di_int a)
|
||||
{
|
||||
static const double twop52 = 4503599627370496.0; // 0x1.0p52
|
||||
static const double twop32 = 4294967296.0; // 0x1.0p32
|
||||
|
||||
union { int64_t x; double d; } low = { .d = twop52 };
|
||||
|
||||
const double high = (int32_t)(a >> 32) * twop32;
|
||||
low.x |= a & INT64_C(0x00000000ffffffff);
|
||||
|
||||
const double result = (high - twop52) + low.d;
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Support for systems that don't have hardware floating-point; there are no flags to
|
||||
* set, and we don't want to code-gen to an unknown soft-float implementation.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI double
|
||||
__floatdidf(di_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(di_int) * CHAR_BIT;
|
||||
const di_int s = a >> (N-1);
|
||||
a = (a ^ s) - s;
|
||||
int sd = N - __builtin_clzll(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > DBL_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit DBL_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit DBL_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case DBL_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case DBL_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = ((du_int)a >> (sd - (DBL_MANT_DIG+2))) |
|
||||
((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */
|
||||
if (a & ((du_int)1 << DBL_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to DBL_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (DBL_MANT_DIG - sd);
|
||||
/* a is now rounded to DBL_MANT_DIG bits */
|
||||
}
|
||||
double_bits fb;
|
||||
fb.u.s.high = ((su_int)s & 0x80000000) | /* sign */
|
||||
((e + 1023) << 20) | /* exponent */
|
||||
((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */
|
||||
fb.u.s.low = (su_int)a; /* mantissa-low */
|
||||
return fb.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI double __aeabi_l2d(di_int a) {
|
||||
return __floatdidf(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI double __aeabi_l2d(di_int a) COMPILER_RT_ALIAS(__floatdidf);
|
||||
#endif
|
||||
#endif
|
91
third_party/compiler_rt/floatdisf.c
vendored
Normal file
91
third_party/compiler_rt/floatdisf.c
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* clang-format off */
|
||||
/*===-- floatdisf.c - Implement __floatdisf -------------------------------===
|
||||
*
|
||||
* 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 __floatdisf for the compiler_rt library.
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
/* Returns: convert a to a float, rounding toward even.*/
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* di_int is a 64 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
COMPILER_RT_ABI float
|
||||
__floatdisf(di_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0F;
|
||||
const unsigned N = sizeof(di_int) * CHAR_BIT;
|
||||
const di_int s = a >> (N-1);
|
||||
a = (a ^ s) - s;
|
||||
int sd = N - __builtin_clzll(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > FLT_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit FLT_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit FLT_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case FLT_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case FLT_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = ((du_int)a >> (sd - (FLT_MANT_DIG+2))) |
|
||||
((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */
|
||||
if (a & ((du_int)1 << FLT_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to FLT_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (FLT_MANT_DIG - sd);
|
||||
/* a is now rounded to FLT_MANT_DIG bits */
|
||||
}
|
||||
float_bits fb;
|
||||
fb.u = ((su_int)s & 0x80000000) | /* sign */
|
||||
((e + 127) << 23) | /* exponent */
|
||||
((su_int)a & 0x007FFFFF); /* mantissa */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI float __aeabi_l2f(di_int a) {
|
||||
return __floatdisf(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI float __aeabi_l2f(di_int a) COMPILER_RT_ALIAS(__floatdisf);
|
||||
#endif
|
||||
#endif
|
53
third_party/compiler_rt/floatditf.c
vendored
Normal file
53
third_party/compiler_rt/floatditf.c
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floatditf.c - integer -> quad-precision conversion ----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements di_int to quad-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
COMPILER_RT_ABI fp_t __floatditf(di_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;
|
||||
du_int aAbs = (du_int)a;
|
||||
if (a < 0) {
|
||||
sign = signBit;
|
||||
aAbs = ~(du_int)a + 1U;
|
||||
}
|
||||
|
||||
// Exponent of (fp_t)a is the width of abs(a).
|
||||
const int exponent = (aWidth - 1) - __builtin_clzll(aAbs);
|
||||
rep_t result;
|
||||
|
||||
// Shift a into the significand field, rounding if it is a right-shift
|
||||
const int shift = significandBits - exponent;
|
||||
result = (rep_t)aAbs << shift ^ implicitBit;
|
||||
|
||||
// Insert the exponent
|
||||
result += (rep_t)(exponent + exponentBias) << significandBits;
|
||||
// Insert the sign bit and return
|
||||
return fromRep(result | sign);
|
||||
}
|
||||
|
||||
#endif
|
49
third_party/compiler_rt/floatdixf.c
vendored
Normal file
49
third_party/compiler_rt/floatdixf.c
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floatdixf.c - Implement __floatdixf -------------------------------===
|
||||
*
|
||||
* 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 __floatdixf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#if !_ARCH_PPC
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: convert a to a long double, rounding toward even. */
|
||||
|
||||
/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
|
||||
* di_int is a 64 bit integral type
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI long double
|
||||
__floatdixf(di_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(di_int) * CHAR_BIT;
|
||||
const di_int s = a >> (N-1);
|
||||
a = (a ^ s) - s;
|
||||
int clz = __builtin_clzll(a);
|
||||
int e = (N - 1) - clz ; /* exponent */
|
||||
long_double_bits fb;
|
||||
fb.u.high.s.low = ((su_int)s & 0x00008000) | /* sign */
|
||||
(e + 16383); /* exponent */
|
||||
fb.u.low.all = a << clz; /* mantissa */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif /* !_ARCH_PPC */
|
64
third_party/compiler_rt/floatsidf.c
vendored
Normal file
64
third_party/compiler_rt/floatsidf.c
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floatsidf.c - integer -> double-precision conversion --*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements integer to double-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
COMPILER_RT_ABI fp_t
|
||||
__floatsidf(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 and clear the implicit bit. Extra
|
||||
// cast to unsigned int is necessary to get the correct behavior for
|
||||
// the input INT_MIN.
|
||||
const int shift = significandBits - exponent;
|
||||
result = (rep_t)(unsigned int)a << shift ^ implicitBit;
|
||||
|
||||
// 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_i2d(int a) {
|
||||
return __floatsidf(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI fp_t __aeabi_i2d(int a) COMPILER_RT_ALIAS(__floatsidf);
|
||||
#endif
|
||||
#endif
|
70
third_party/compiler_rt/floatsisf.c
vendored
Normal file
70
third_party/compiler_rt/floatsisf.c
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* clang-format off */
|
||||
//===-- 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#include "third_party/compiler_rt/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
|
||||
AEABI_RTABI fp_t __aeabi_i2f(int a) COMPILER_RT_ALIAS(__floatsisf);
|
||||
#endif
|
||||
#endif
|
53
third_party/compiler_rt/floatsitf.c
vendored
Normal file
53
third_party/compiler_rt/floatsitf.c
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floatsitf.c - integer -> quad-precision conversion ----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements integer to quad-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
COMPILER_RT_ABI fp_t __floatsitf(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;
|
||||
unsigned aAbs = (unsigned)a;
|
||||
if (a < 0) {
|
||||
sign = signBit;
|
||||
aAbs = ~(unsigned)a + 1U;
|
||||
}
|
||||
|
||||
// Exponent of (fp_t)a is the width of abs(a).
|
||||
const int exponent = (aWidth - 1) - __builtin_clz(aAbs);
|
||||
rep_t result;
|
||||
|
||||
// Shift a into the significand field and clear the implicit bit.
|
||||
const int shift = significandBits - exponent;
|
||||
result = (rep_t)aAbs << shift ^ implicitBit;
|
||||
|
||||
// Insert the exponent
|
||||
result += (rep_t)(exponent + exponentBias) << significandBits;
|
||||
// Insert the sign bit and return
|
||||
return fromRep(result | sign);
|
||||
}
|
||||
|
||||
#endif
|
86
third_party/compiler_rt/floattidf.c
vendored
Normal file
86
third_party/compiler_rt/floattidf.c
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floattidf.c - Implement __floattidf -------------------------------===
|
||||
*
|
||||
* 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 __floattidf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a double, rounding toward even.*/
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* ti_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
COMPILER_RT_ABI double
|
||||
__floattidf(ti_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(ti_int) * CHAR_BIT;
|
||||
const ti_int s = a >> (N-1);
|
||||
a = (a ^ s) - s;
|
||||
int sd = N - __clzti2(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > DBL_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit DBL_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit DBL_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case DBL_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case DBL_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = ((tu_int)a >> (sd - (DBL_MANT_DIG+2))) |
|
||||
((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */
|
||||
if (a & ((tu_int)1 << DBL_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to DBL_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (DBL_MANT_DIG - sd);
|
||||
/* a is now rounded to DBL_MANT_DIG bits */
|
||||
}
|
||||
double_bits fb;
|
||||
fb.u.s.high = ((su_int)s & 0x80000000) | /* sign */
|
||||
((e + 1023) << 20) | /* exponent */
|
||||
((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */
|
||||
fb.u.s.low = (su_int)a; /* mantissa-low */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
85
third_party/compiler_rt/floattisf.c
vendored
Normal file
85
third_party/compiler_rt/floattisf.c
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floattisf.c - Implement __floattisf -------------------------------===
|
||||
*
|
||||
* 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 __floattisf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a float, rounding toward even. */
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* ti_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
COMPILER_RT_ABI float
|
||||
__floattisf(ti_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0F;
|
||||
const unsigned N = sizeof(ti_int) * CHAR_BIT;
|
||||
const ti_int s = a >> (N-1);
|
||||
a = (a ^ s) - s;
|
||||
int sd = N - __clzti2(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > FLT_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit FLT_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit FLT_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case FLT_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case FLT_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = ((tu_int)a >> (sd - (FLT_MANT_DIG+2))) |
|
||||
((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */
|
||||
if (a & ((tu_int)1 << FLT_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to FLT_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (FLT_MANT_DIG - sd);
|
||||
/* a is now rounded to FLT_MANT_DIG bits */
|
||||
}
|
||||
float_bits fb;
|
||||
fb.u = ((su_int)s & 0x80000000) | /* sign */
|
||||
((e + 127) << 23) | /* exponent */
|
||||
((su_int)a & 0x007FFFFF); /* mantissa */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
85
third_party/compiler_rt/floattitf.c
vendored
Normal file
85
third_party/compiler_rt/floattitf.c
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floattitf.c - int128 -> quad-precision conversion -----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements ti_int to quad-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: convert a ti_int to a fp_t, rounding toward even. */
|
||||
|
||||
/* Assumption: fp_t is a IEEE 128 bit floating point type
|
||||
* ti_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm |
|
||||
* mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
COMPILER_RT_ABI fp_t
|
||||
__floattitf(ti_int a) {
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(ti_int) * CHAR_BIT;
|
||||
const ti_int s = a >> (N-1);
|
||||
a = (a ^ s) - s;
|
||||
int sd = N - __clzti2(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > LDBL_MANT_DIG) {
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit LDBL_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit LDBL_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd) {
|
||||
case LDBL_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case LDBL_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) |
|
||||
((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */
|
||||
if (a & ((tu_int)1 << LDBL_MANT_DIG)) {
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to LDBL_MANT_DIG bits */
|
||||
} else {
|
||||
a <<= (LDBL_MANT_DIG - sd);
|
||||
/* a is now rounded to LDBL_MANT_DIG bits */
|
||||
}
|
||||
|
||||
long_double_bits fb;
|
||||
fb.u.high.all = (s & 0x8000000000000000LL) /* sign */
|
||||
| (du_int)(e + 16383) << 48 /* exponent */
|
||||
| ((a >> 64) & 0x0000ffffffffffffLL); /* significand */
|
||||
fb.u.low.all = (du_int)(a);
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif
|
87
third_party/compiler_rt/floattixf.c
vendored
Normal file
87
third_party/compiler_rt/floattixf.c
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floattixf.c - Implement __floattixf -------------------------------===
|
||||
*
|
||||
* 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 __floattixf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a long double, rounding toward even. */
|
||||
|
||||
/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
|
||||
* ti_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI long double
|
||||
__floattixf(ti_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(ti_int) * CHAR_BIT;
|
||||
const ti_int s = a >> (N-1);
|
||||
a = (a ^ s) - s;
|
||||
int sd = N - __clzti2(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > LDBL_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit LDBL_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit LDBL_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case LDBL_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case LDBL_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) |
|
||||
((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */
|
||||
if (a & ((tu_int)1 << LDBL_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to LDBL_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (LDBL_MANT_DIG - sd);
|
||||
/* a is now rounded to LDBL_MANT_DIG bits */
|
||||
}
|
||||
long_double_bits fb;
|
||||
fb.u.high.s.low = ((su_int)s & 0x8000) | /* sign */
|
||||
(e + 16383); /* exponent */
|
||||
fb.u.low.all = (du_int)a; /* mantissa */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
118
third_party/compiler_rt/floatundidf.c
vendored
Normal file
118
third_party/compiler_rt/floatundidf.c
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floatundidf.c - Implement __floatundidf ---------------------------===
|
||||
*
|
||||
* 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 __floatundidf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
/* Returns: convert a to a double, rounding toward even. */
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* du_int is a 64 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifndef __SOFT_FP__
|
||||
/* Support for systems that have hardware floating-point; we'll set the inexact flag
|
||||
* as a side-effect of this computation.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI double
|
||||
__floatundidf(du_int a)
|
||||
{
|
||||
static const double twop52 = 4503599627370496.0; // 0x1.0p52
|
||||
static const double twop84 = 19342813113834066795298816.0; // 0x1.0p84
|
||||
static const double twop84_plus_twop52 = 19342813118337666422669312.0; // 0x1.00000001p84
|
||||
|
||||
union { uint64_t x; double d; } high = { .d = twop84 };
|
||||
union { uint64_t x; double d; } low = { .d = twop52 };
|
||||
|
||||
high.x |= a >> 32;
|
||||
low.x |= a & UINT64_C(0x00000000ffffffff);
|
||||
|
||||
const double result = (high.d - twop84_plus_twop52) + low.d;
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Support for systems that don't have hardware floating-point; there are no flags to
|
||||
* set, and we don't want to code-gen to an unknown soft-float implementation.
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI double
|
||||
__floatundidf(du_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(du_int) * CHAR_BIT;
|
||||
int sd = N - __builtin_clzll(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > DBL_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit DBL_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit DBL_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case DBL_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case DBL_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = (a >> (sd - (DBL_MANT_DIG+2))) |
|
||||
((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */
|
||||
if (a & ((du_int)1 << DBL_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to DBL_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (DBL_MANT_DIG - sd);
|
||||
/* a is now rounded to DBL_MANT_DIG bits */
|
||||
}
|
||||
double_bits fb;
|
||||
fb.u.s.high = ((e + 1023) << 20) | /* exponent */
|
||||
((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */
|
||||
fb.u.s.low = (su_int)a; /* mantissa-low */
|
||||
return fb.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI double __aeabi_ul2d(du_int a) {
|
||||
return __floatundidf(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI double __aeabi_ul2d(du_int a) COMPILER_RT_ALIAS(__floatundidf);
|
||||
#endif
|
||||
#endif
|
88
third_party/compiler_rt/floatundisf.c
vendored
Normal file
88
third_party/compiler_rt/floatundisf.c
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* clang-format off */
|
||||
/*===-- floatundisf.c - Implement __floatundisf ---------------------------===
|
||||
*
|
||||
* 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 __floatundisf for the compiler_rt library.
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
/* Returns: convert a to a float, rounding toward even. */
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* du_int is a 64 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
COMPILER_RT_ABI float
|
||||
__floatundisf(du_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0F;
|
||||
const unsigned N = sizeof(du_int) * CHAR_BIT;
|
||||
int sd = N - __builtin_clzll(a); /* number of significant digits */
|
||||
int e = sd - 1; /* 8 exponent */
|
||||
if (sd > FLT_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit FLT_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit FLT_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case FLT_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case FLT_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = (a >> (sd - (FLT_MANT_DIG+2))) |
|
||||
((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */
|
||||
if (a & ((du_int)1 << FLT_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to FLT_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (FLT_MANT_DIG - sd);
|
||||
/* a is now rounded to FLT_MANT_DIG bits */
|
||||
}
|
||||
float_bits fb;
|
||||
fb.u = ((e + 127) << 23) | /* exponent */
|
||||
((su_int)a & 0x007FFFFF); /* mantissa */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
AEABI_RTABI float __aeabi_ul2f(du_int a) {
|
||||
return __floatundisf(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI float __aeabi_ul2f(du_int a) COMPILER_RT_ALIAS(__floatundisf);
|
||||
#endif
|
||||
#endif
|
43
third_party/compiler_rt/floatunditf.c
vendored
Normal file
43
third_party/compiler_rt/floatunditf.c
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floatunditf.c - uint -> quad-precision conversion -----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements du_int to quad-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
COMPILER_RT_ABI fp_t __floatunditf(du_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_clzll(a);
|
||||
rep_t result;
|
||||
|
||||
// Shift a into the significand field and clear the implicit bit.
|
||||
const int shift = significandBits - exponent;
|
||||
result = (rep_t)a << shift ^ implicitBit;
|
||||
|
||||
// Insert the exponent
|
||||
result += (rep_t)(exponent + exponentBias) << significandBits;
|
||||
return fromRep(result);
|
||||
}
|
||||
|
||||
#endif
|
45
third_party/compiler_rt/floatundixf.c
vendored
Normal file
45
third_party/compiler_rt/floatundixf.c
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floatundixf.c - Implement __floatundixf ---------------------------===
|
||||
*
|
||||
* 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 __floatundixf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#if !_ARCH_PPC
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: convert a to a long double, rounding toward even. */
|
||||
|
||||
/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
|
||||
* du_int is a 64 bit integral type
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
COMPILER_RT_ABI long double
|
||||
__floatundixf(du_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(du_int) * CHAR_BIT;
|
||||
int clz = __builtin_clzll(a);
|
||||
int e = (N - 1) - clz ; /* exponent */
|
||||
long_double_bits fb;
|
||||
fb.u.high.s.low = (e + 16383); /* exponent */
|
||||
fb.u.low.all = a << clz; /* mantissa */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif /* _ARCH_PPC */
|
53
third_party/compiler_rt/floatunsidf.c
vendored
Normal file
53
third_party/compiler_rt/floatunsidf.c
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floatunsidf.c - uint -> double-precision conversion ---*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements unsigned integer to double-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define DOUBLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
COMPILER_RT_ABI fp_t
|
||||
__floatunsidf(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 and clear the implicit bit.
|
||||
const int shift = significandBits - exponent;
|
||||
result = (rep_t)a << shift ^ implicitBit;
|
||||
|
||||
// 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_ui2d(unsigned int a) {
|
||||
return __floatunsidf(a);
|
||||
}
|
||||
#else
|
||||
AEABI_RTABI fp_t __aeabi_ui2d(unsigned int a) COMPILER_RT_ALIAS(__floatunsidf);
|
||||
#endif
|
||||
#endif
|
61
third_party/compiler_rt/floatunsisf.c
vendored
Normal file
61
third_party/compiler_rt/floatunsisf.c
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements unsigned integer to single-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#include "third_party/compiler_rt/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
|
||||
AEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) COMPILER_RT_ALIAS(__floatunsisf);
|
||||
#endif
|
||||
#endif
|
43
third_party/compiler_rt/floatunsitf.c
vendored
Normal file
43
third_party/compiler_rt/floatunsitf.c
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floatunsitf.c - uint -> quad-precision conversion -----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements unsigned integer to quad-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
COMPILER_RT_ABI fp_t __floatunsitf(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 and clear the implicit bit.
|
||||
const int shift = significandBits - exponent;
|
||||
result = (rep_t)a << shift ^ implicitBit;
|
||||
|
||||
// Insert the exponent
|
||||
result += (rep_t)(exponent + exponentBias) << significandBits;
|
||||
return fromRep(result);
|
||||
}
|
||||
|
||||
#endif
|
83
third_party/compiler_rt/floatuntidf.c
vendored
Normal file
83
third_party/compiler_rt/floatuntidf.c
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floatuntidf.c - Implement __floatuntidf ---------------------------===
|
||||
*
|
||||
* 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 __floatuntidf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a double, rounding toward even. */
|
||||
|
||||
/* Assumption: double is a IEEE 64 bit floating point type
|
||||
* tu_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
COMPILER_RT_ABI double
|
||||
__floatuntidf(tu_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(tu_int) * CHAR_BIT;
|
||||
int sd = N - __clzti2(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > DBL_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit DBL_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit DBL_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case DBL_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case DBL_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = (a >> (sd - (DBL_MANT_DIG+2))) |
|
||||
((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */
|
||||
if (a & ((tu_int)1 << DBL_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to DBL_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (DBL_MANT_DIG - sd);
|
||||
/* a is now rounded to DBL_MANT_DIG bits */
|
||||
}
|
||||
double_bits fb;
|
||||
fb.u.s.high = ((e + 1023) << 20) | /* exponent */
|
||||
((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */
|
||||
fb.u.s.low = (su_int)a; /* mantissa-low */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
82
third_party/compiler_rt/floatuntisf.c
vendored
Normal file
82
third_party/compiler_rt/floatuntisf.c
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floatuntisf.c - Implement __floatuntisf ---------------------------===
|
||||
*
|
||||
* 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 __floatuntisf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a float, rounding toward even. */
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* tu_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
COMPILER_RT_ABI float
|
||||
__floatuntisf(tu_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0F;
|
||||
const unsigned N = sizeof(tu_int) * CHAR_BIT;
|
||||
int sd = N - __clzti2(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > FLT_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit FLT_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit FLT_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case FLT_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case FLT_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = (a >> (sd - (FLT_MANT_DIG+2))) |
|
||||
((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */
|
||||
if (a & ((tu_int)1 << FLT_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to FLT_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (FLT_MANT_DIG - sd);
|
||||
/* a is now rounded to FLT_MANT_DIG bits */
|
||||
}
|
||||
float_bits fb;
|
||||
fb.u = ((e + 127) << 23) | /* exponent */
|
||||
((su_int)a & 0x007FFFFF); /* mantissa */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
82
third_party/compiler_rt/floatuntitf.c
vendored
Normal file
82
third_party/compiler_rt/floatuntitf.c
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/floatuntitf.c - uint128 -> quad-precision conversion --*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements tu_int to quad-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
/* Returns: convert a tu_int to a fp_t, rounding toward even. */
|
||||
|
||||
/* Assumption: fp_t is a IEEE 128 bit floating point type
|
||||
* tu_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm |
|
||||
* mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
|
||||
COMPILER_RT_ABI fp_t
|
||||
__floatuntitf(tu_int a) {
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(tu_int) * CHAR_BIT;
|
||||
int sd = N - __clzti2(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > LDBL_MANT_DIG) {
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit LDBL_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit LDBL_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd) {
|
||||
case LDBL_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case LDBL_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = (a >> (sd - (LDBL_MANT_DIG+2))) |
|
||||
((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */
|
||||
if (a & ((tu_int)1 << LDBL_MANT_DIG)) {
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to LDBL_MANT_DIG bits */
|
||||
} else {
|
||||
a <<= (LDBL_MANT_DIG - sd);
|
||||
/* a is now rounded to LDBL_MANT_DIG bits */
|
||||
}
|
||||
|
||||
long_double_bits fb;
|
||||
fb.u.high.all = (du_int)(e + 16383) << 48 /* exponent */
|
||||
| ((a >> 64) & 0x0000ffffffffffffLL); /* significand */
|
||||
fb.u.low.all = (du_int)(a);
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif
|
84
third_party/compiler_rt/floatuntixf.c
vendored
Normal file
84
third_party/compiler_rt/floatuntixf.c
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* clang-format off */
|
||||
/* ===-- floatuntixf.c - Implement __floatuntixf ---------------------------===
|
||||
*
|
||||
* 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 __floatuntixf for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
|
||||
/* Returns: convert a to a long double, rounding toward even. */
|
||||
|
||||
/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
|
||||
* tu_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
|
||||
* 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI long double
|
||||
__floatuntixf(tu_int a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(tu_int) * CHAR_BIT;
|
||||
int sd = N - __clzti2(a); /* number of significant digits */
|
||||
int e = sd - 1; /* exponent */
|
||||
if (sd > LDBL_MANT_DIG)
|
||||
{
|
||||
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
* 12345678901234567890123456
|
||||
* 1 = msb 1 bit
|
||||
* P = bit LDBL_MANT_DIG-1 bits to the right of 1
|
||||
* Q = bit LDBL_MANT_DIG bits to the right of 1
|
||||
* R = "or" of all bits to the right of Q
|
||||
*/
|
||||
switch (sd)
|
||||
{
|
||||
case LDBL_MANT_DIG + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case LDBL_MANT_DIG + 2:
|
||||
break;
|
||||
default:
|
||||
a = (a >> (sd - (LDBL_MANT_DIG+2))) |
|
||||
((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
|
||||
};
|
||||
/* finish: */
|
||||
a |= (a & 4) != 0; /* Or P into R */
|
||||
++a; /* round - this step may add a significant bit */
|
||||
a >>= 2; /* dump Q and R */
|
||||
/* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */
|
||||
if (a & ((tu_int)1 << LDBL_MANT_DIG))
|
||||
{
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
/* a is now rounded to LDBL_MANT_DIG bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
a <<= (LDBL_MANT_DIG - sd);
|
||||
/* a is now rounded to LDBL_MANT_DIG bits */
|
||||
}
|
||||
long_double_bits fb;
|
||||
fb.u.high.s.low = (e + 16383); /* exponent */
|
||||
fb.u.low.all = (du_int)a; /* mantissa */
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif
|
146
third_party/compiler_rt/fp_add_impl.inc
vendored
Normal file
146
third_party/compiler_rt/fp_add_impl.inc
vendored
Normal file
|
@ -0,0 +1,146 @@
|
|||
/* clang-format off */
|
||||
//===----- lib/fp_add_impl.inc - floaing point 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements soft-float addition with the IEEE-754 default rounding
|
||||
// (to nearest, ties to even).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
static __inline fp_t __addXf3__(fp_t a, fp_t b) {
|
||||
rep_t aRep = toRep(a);
|
||||
rep_t bRep = toRep(b);
|
||||
const rep_t aAbs = aRep & absMask;
|
||||
const rep_t bAbs = bRep & absMask;
|
||||
|
||||
// Detect if a or b is zero, infinity, or NaN.
|
||||
if (aAbs - REP_C(1) >= infRep - REP_C(1) ||
|
||||
bAbs - REP_C(1) >= infRep - REP_C(1)) {
|
||||
// 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 bool subtraction = (aRep ^ bRep) & signBit;
|
||||
|
||||
// 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 bool sticky = bSignificand << (typeWidth - align);
|
||||
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 bool 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 bool sticky = aSignificand << (typeWidth - shift);
|
||||
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);
|
||||
}
|
93
third_party/compiler_rt/fp_extend_common.inc
vendored
Normal file
93
third_party/compiler_rt/fp_extend_common.inc
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* clang-format off */
|
||||
//===-lib/fp_extend.h - low precision -> high 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Set source and destination setting
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef FP_EXTEND_HEADER
|
||||
#define FP_EXTEND_HEADER
|
||||
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#if defined SRC_SINGLE
|
||||
typedef float src_t;
|
||||
typedef uint32_t src_rep_t;
|
||||
#define SRC_REP_C UINT32_C
|
||||
static const int srcSigBits = 23;
|
||||
#define src_rep_t_clz __builtin_clz
|
||||
|
||||
#elif defined SRC_DOUBLE
|
||||
typedef double src_t;
|
||||
typedef uint64_t src_rep_t;
|
||||
#define SRC_REP_C UINT64_C
|
||||
static const int srcSigBits = 52;
|
||||
static __inline int src_rep_t_clz(src_rep_t a) {
|
||||
#if defined __LP64__
|
||||
return __builtin_clzl(a);
|
||||
#else
|
||||
if (a & REP_C(0xffffffff00000000))
|
||||
return __builtin_clz(a >> 32);
|
||||
else
|
||||
return 32 + __builtin_clz(a & REP_C(0xffffffff));
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined SRC_HALF
|
||||
typedef uint16_t src_t;
|
||||
typedef uint16_t src_rep_t;
|
||||
#define SRC_REP_C UINT16_C
|
||||
static const int srcSigBits = 10;
|
||||
#define src_rep_t_clz __builtin_clz
|
||||
|
||||
#else
|
||||
#error Source should be half, single, or double precision!
|
||||
#endif //end source precision
|
||||
|
||||
#undef DST_REP_C
|
||||
|
||||
#if defined DST_SINGLE
|
||||
typedef float dst_t;
|
||||
typedef uint32_t dst_rep_t;
|
||||
#define DST_REP_C UINT32_C
|
||||
static const int dstSigBits = 23;
|
||||
|
||||
#elif defined DST_DOUBLE
|
||||
typedef double dst_t;
|
||||
typedef uint64_t dst_rep_t;
|
||||
#define DST_REP_C UINT64_C
|
||||
static const int dstSigBits = 52;
|
||||
|
||||
#elif defined DST_QUAD
|
||||
typedef long double dst_t;
|
||||
typedef __uint128_t dst_rep_t;
|
||||
#define DST_REP_C (__uint128_t)
|
||||
static const int dstSigBits = 112;
|
||||
|
||||
#else
|
||||
#error Destination should be single, double, or quad precision!
|
||||
#endif //end destination precision
|
||||
|
||||
// End of specialization parameters. Two helper routines for conversion to and
|
||||
// from the representation of floating-point data as integer values follow.
|
||||
|
||||
static __inline src_rep_t srcToRep(src_t x) {
|
||||
const union { src_t f; src_rep_t i; } rep = {.f = x};
|
||||
return rep.i;
|
||||
}
|
||||
|
||||
static __inline dst_t dstFromRep(dst_rep_t x) {
|
||||
const union { dst_t f; dst_rep_t i; } rep = {.i = x};
|
||||
return rep.f;
|
||||
}
|
||||
// End helper routines. Conversion implementation follows.
|
||||
|
||||
#endif //FP_EXTEND_HEADER
|
110
third_party/compiler_rt/fp_extend_impl.inc
vendored
Normal file
110
third_party/compiler_rt/fp_extend_impl.inc
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* clang-format off */
|
||||
//=-lib/fp_extend_impl.inc - low precision -> high precision conversion -*-- -//
|
||||
//
|
||||
// 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 a fairly generic conversion from a narrower to a wider
|
||||
// IEEE-754 floating-point type. The constants and types defined following the
|
||||
// includes below parameterize the conversion.
|
||||
//
|
||||
// It does not support types that don't use the usual IEEE-754 interchange
|
||||
// formats; specifically, some work would be needed to adapt it to
|
||||
// (for example) the Intel 80-bit format or PowerPC double-double format.
|
||||
//
|
||||
// Note please, however, that this implementation is only intended to support
|
||||
// *widening* operations; if you need to convert to a *narrower* floating-point
|
||||
// type (e.g. double -> float), then this routine will not do what you want it
|
||||
// to.
|
||||
//
|
||||
// It also requires that integer types at least as large as both formats
|
||||
// are available on the target platform; this may pose a problem when trying
|
||||
// to add support for quad on some 32-bit systems, for example. You also may
|
||||
// run into trouble finding an appropriate CLZ function for wide source types;
|
||||
// you will likely need to roll your own on some platforms.
|
||||
//
|
||||
// Finally, the following assumptions are made:
|
||||
//
|
||||
// 1. floating-point types and integer types have the same endianness on the
|
||||
// target platform
|
||||
//
|
||||
// 2. quiet NaNs, if supported, are indicated by the leading bit of the
|
||||
// significand field being set
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/fp_extend_common.inc"
|
||||
|
||||
static __inline dst_t __extendXfYf2__(src_t a) {
|
||||
// Various constants whose values follow from the type parameters.
|
||||
// Any reasonable optimizer will fold and propagate all of these.
|
||||
const int srcBits = sizeof(src_t)*CHAR_BIT;
|
||||
const int srcExpBits = srcBits - srcSigBits - 1;
|
||||
const int srcInfExp = (1u << srcExpBits) - 1;
|
||||
const int srcExpBias = srcInfExp >> 1;
|
||||
|
||||
const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits;
|
||||
const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits;
|
||||
const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits);
|
||||
const src_rep_t srcAbsMask = srcSignMask - 1;
|
||||
const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1);
|
||||
const src_rep_t srcNaNCode = srcQNaN - 1;
|
||||
|
||||
const int dstBits = sizeof(dst_t)*CHAR_BIT;
|
||||
const int dstExpBits = dstBits - dstSigBits - 1;
|
||||
const int dstInfExp = (1u << dstExpBits) - 1;
|
||||
const int dstExpBias = dstInfExp >> 1;
|
||||
|
||||
const dst_rep_t dstMinNormal = DST_REP_C(1) << dstSigBits;
|
||||
|
||||
// Break a into a sign and representation of the absolute value
|
||||
const src_rep_t aRep = srcToRep(a);
|
||||
const src_rep_t aAbs = aRep & srcAbsMask;
|
||||
const src_rep_t sign = aRep & srcSignMask;
|
||||
dst_rep_t absResult;
|
||||
|
||||
// If sizeof(src_rep_t) < sizeof(int), the subtraction result is promoted
|
||||
// to (signed) int. To avoid that, explicitly cast to src_rep_t.
|
||||
if ((src_rep_t)(aAbs - srcMinNormal) < srcInfinity - srcMinNormal) {
|
||||
// a is a normal number.
|
||||
// Extend to the destination type by shifting the significand and
|
||||
// exponent into the proper position and rebiasing the exponent.
|
||||
absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits);
|
||||
absResult += (dst_rep_t)(dstExpBias - srcExpBias) << dstSigBits;
|
||||
}
|
||||
|
||||
else if (aAbs >= srcInfinity) {
|
||||
// a is NaN or infinity.
|
||||
// Conjure the result by beginning with infinity, then setting the qNaN
|
||||
// bit (if needed) and right-aligning the rest of the trailing NaN
|
||||
// payload field.
|
||||
absResult = (dst_rep_t)dstInfExp << dstSigBits;
|
||||
absResult |= (dst_rep_t)(aAbs & srcQNaN) << (dstSigBits - srcSigBits);
|
||||
absResult |= (dst_rep_t)(aAbs & srcNaNCode) << (dstSigBits - srcSigBits);
|
||||
}
|
||||
|
||||
else if (aAbs) {
|
||||
// a is denormal.
|
||||
// renormalize the significand and clear the leading bit, then insert
|
||||
// the correct adjusted exponent in the destination type.
|
||||
const int scale = src_rep_t_clz(aAbs) - src_rep_t_clz(srcMinNormal);
|
||||
absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits + scale);
|
||||
absResult ^= dstMinNormal;
|
||||
const int resultExponent = dstExpBias - srcExpBias - scale + 1;
|
||||
absResult |= (dst_rep_t)resultExponent << dstSigBits;
|
||||
}
|
||||
|
||||
else {
|
||||
// a is zero.
|
||||
absResult = 0;
|
||||
}
|
||||
|
||||
// Apply the signbit to (dst_t)abs(a).
|
||||
const dst_rep_t result = absResult | (dst_rep_t)sign << (dstBits - srcBits);
|
||||
return dstFromRep(result);
|
||||
}
|
42
third_party/compiler_rt/fp_fixint_impl.inc
vendored
Normal file
42
third_party/compiler_rt/fp_fixint_impl.inc
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements float to integer conversion for the
|
||||
// compiler-rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
static __inline fixint_t __fixint(fp_t a) {
|
||||
const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2);
|
||||
const fixint_t fixint_min = -fixint_max - 1;
|
||||
// Break a into sign, exponent, significand
|
||||
const rep_t aRep = toRep(a);
|
||||
const rep_t aAbs = aRep & absMask;
|
||||
const fixint_t sign = aRep & signBit ? -1 : 1;
|
||||
const int exponent = (aAbs >> significandBits) - exponentBias;
|
||||
const rep_t significand = (aAbs & significandMask) | implicitBit;
|
||||
|
||||
// If exponent is negative, the result is zero.
|
||||
if (exponent < 0)
|
||||
return 0;
|
||||
|
||||
// If the value is too large for the integer type, saturate.
|
||||
if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT)
|
||||
return sign == 1 ? fixint_max : fixint_min;
|
||||
|
||||
// If 0 <= exponent < significandBits, right shift to get the result.
|
||||
// Otherwise, shift left.
|
||||
if (exponent < significandBits)
|
||||
return sign * (significand >> (significandBits - exponent));
|
||||
else
|
||||
return sign * ((fixint_t)significand << (exponent - significandBits));
|
||||
}
|
40
third_party/compiler_rt/fp_fixuint_impl.inc
vendored
Normal file
40
third_party/compiler_rt/fp_fixuint_impl.inc
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* clang-format off */
|
||||
//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements float to unsigned integer conversion for the
|
||||
// compiler-rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
static __inline fixuint_t __fixuint(fp_t a) {
|
||||
// Break a into sign, exponent, significand
|
||||
const rep_t aRep = toRep(a);
|
||||
const rep_t aAbs = aRep & absMask;
|
||||
const int sign = aRep & signBit ? -1 : 1;
|
||||
const int exponent = (aAbs >> significandBits) - exponentBias;
|
||||
const rep_t significand = (aAbs & significandMask) | implicitBit;
|
||||
|
||||
// If either the value or the exponent is negative, the result is zero.
|
||||
if (sign == -1 || exponent < 0)
|
||||
return 0;
|
||||
|
||||
// If the value is too large for the integer type, saturate.
|
||||
if ((unsigned)exponent >= sizeof(fixuint_t) * CHAR_BIT)
|
||||
return ~(fixuint_t)0;
|
||||
|
||||
// If 0 <= exponent < significandBits, right shift to get the result.
|
||||
// Otherwise, shift left.
|
||||
if (exponent < significandBits)
|
||||
return significand >> (significandBits - exponent);
|
||||
else
|
||||
return (fixuint_t)significand << (exponent - significandBits);
|
||||
}
|
314
third_party/compiler_rt/fp_lib.inc
vendored
Normal file
314
third_party/compiler_rt/fp_lib.inc
vendored
Normal file
|
@ -0,0 +1,314 @@
|
|||
/* clang-format off */
|
||||
//===-- 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "libc/literal.h"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
#include "third_party/compiler_rt/int_math.h"
|
||||
|
||||
#if defined SINGLE_PRECISION
|
||||
|
||||
typedef uint32_t rep_t;
|
||||
typedef int32_t srep_t;
|
||||
typedef float fp_t;
|
||||
#define REP_C UINT32_C
|
||||
#define significandBits 23
|
||||
|
||||
static __inline int rep_clz(rep_t a) {
|
||||
return __builtin_clz(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 uint64_t rep_t;
|
||||
typedef int64_t srep_t;
|
||||
typedef double fp_t;
|
||||
#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 __builtin_clz(a >> 32);
|
||||
else
|
||||
return 32 + __builtin_clz(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
|
||||
#define CRT_LDBL_128BIT
|
||||
typedef __uint128_t rep_t;
|
||||
typedef __int128_t srep_t;
|
||||
typedef long double fp_t;
|
||||
#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
|
||||
#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 ((1u << 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);
|
||||
*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
|
118
third_party/compiler_rt/fp_mul_impl.inc
vendored
Normal file
118
third_party/compiler_rt/fp_mul_impl.inc
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* clang-format off */
|
||||
//===---- lib/fp_mul_impl.inc - floating point 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements soft-float multiplication with the IEEE-754 default
|
||||
// rounding (to nearest, ties to even).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "libc/literal.h"
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
||||
static __inline fp_t __mulXf3__(fp_t a, fp_t b) {
|
||||
const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
|
||||
const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
|
||||
const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit;
|
||||
|
||||
rep_t aSignificand = toRep(a) & significandMask;
|
||||
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
|
||||
//
|
||||
// If the result is so small that it just underflows to zero, return
|
||||
// a zero of the appropriate sign. Mathematically there is no need to
|
||||
// handle this case separately, but we make it a special case to
|
||||
// simplify the shift logic.
|
||||
const unsigned int shift = REP_C(1) - (unsigned int)productExponent;
|
||||
if (shift >= typeWidth) return fromRep(productSign);
|
||||
|
||||
// Otherwise, shift the significand of the result so that the round
|
||||
// bit is the high bit of productLo.
|
||||
wideRightShiftWithSticky(&productHi, &productLo, shift);
|
||||
}
|
||||
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. We use the
|
||||
// default IEEE-754 round-to-nearest, ties-to-even rounding mode.
|
||||
if (productLo > signBit) productHi++;
|
||||
if (productLo == signBit) productHi += productHi & 1;
|
||||
return fromRep(productHi);
|
||||
}
|
137
third_party/compiler_rt/fp_trunc.inc
vendored
Normal file
137
third_party/compiler_rt/fp_trunc.inc
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* clang-format off */
|
||||
//= lib/fp_trunc_impl.inc - high precision -> low precision conversion *-*-===//
|
||||
//
|
||||
// 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 a fairly generic conversion from a wider to a narrower
|
||||
// IEEE-754 floating-point type in the default (round to nearest, ties to even)
|
||||
// rounding mode. The constants and types defined following the includes below
|
||||
// parameterize the conversion.
|
||||
//
|
||||
// This routine can be trivially adapted to support conversions to
|
||||
// half-precision or from quad-precision. It does not support types that don't
|
||||
// use the usual IEEE-754 interchange formats; specifically, some work would be
|
||||
// needed to adapt it to (for example) the Intel 80-bit format or PowerPC
|
||||
// double-double format.
|
||||
//
|
||||
// Note please, however, that this implementation is only intended to support
|
||||
// *narrowing* operations; if you need to convert to a *wider* floating-point
|
||||
// type (e.g. float -> double), then this routine will not do what you want it
|
||||
// to.
|
||||
//
|
||||
// It also requires that integer types at least as large as both formats
|
||||
// are available on the target platform; this may pose a problem when trying
|
||||
// to add support for quad on some 32-bit systems, for example.
|
||||
//
|
||||
// Finally, the following assumptions are made:
|
||||
//
|
||||
// 1. floating-point types and integer types have the same endianness on the
|
||||
// target platform
|
||||
//
|
||||
// 2. quiet NaNs, if supported, are indicated by the leading bit of the
|
||||
// significand field being set
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "third_party/compiler_rt/fp_trunc_common.inc"
|
||||
#include "libc/literal.h"
|
||||
|
||||
static __inline dst_t __truncXfYf2__(src_t a) {
|
||||
// Various constants whose values follow from the type parameters.
|
||||
// Any reasonable optimizer will fold and propagate all of these.
|
||||
const int srcBits = sizeof(src_t)*CHAR_BIT;
|
||||
const int srcExpBits = srcBits - srcSigBits - 1;
|
||||
const int srcInfExp = (1u << srcExpBits) - 1;
|
||||
const int srcExpBias = srcInfExp >> 1;
|
||||
|
||||
const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits;
|
||||
const src_rep_t srcSignificandMask = srcMinNormal - 1;
|
||||
const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits;
|
||||
const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits);
|
||||
const src_rep_t srcAbsMask = srcSignMask - 1;
|
||||
const src_rep_t roundMask = (SRC_REP_C(1) << (srcSigBits - dstSigBits)) - 1;
|
||||
const src_rep_t halfway = SRC_REP_C(1) << (srcSigBits - dstSigBits - 1);
|
||||
const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1);
|
||||
const src_rep_t srcNaNCode = srcQNaN - 1;
|
||||
|
||||
const int dstBits = sizeof(dst_t)*CHAR_BIT;
|
||||
const int dstExpBits = dstBits - dstSigBits - 1;
|
||||
const int dstInfExp = (1u << dstExpBits) - 1;
|
||||
const int dstExpBias = dstInfExp >> 1;
|
||||
|
||||
const int underflowExponent = srcExpBias + 1 - dstExpBias;
|
||||
const int overflowExponent = srcExpBias + dstInfExp - dstExpBias;
|
||||
const src_rep_t underflow = (src_rep_t)underflowExponent << srcSigBits;
|
||||
const src_rep_t overflow = (src_rep_t)overflowExponent << srcSigBits;
|
||||
|
||||
const dst_rep_t dstQNaN = DST_REP_C(1) << (dstSigBits - 1);
|
||||
const dst_rep_t dstNaNCode = dstQNaN - 1;
|
||||
|
||||
// Break a into a sign and representation of the absolute value
|
||||
const src_rep_t aRep = srcToRep(a);
|
||||
const src_rep_t aAbs = aRep & srcAbsMask;
|
||||
const src_rep_t sign = aRep & srcSignMask;
|
||||
dst_rep_t absResult;
|
||||
|
||||
if (aAbs - underflow < aAbs - overflow) {
|
||||
// The exponent of a is within the range of normal numbers in the
|
||||
// destination format. We can convert by simply right-shifting with
|
||||
// rounding and adjusting the exponent.
|
||||
absResult = aAbs >> (srcSigBits - dstSigBits);
|
||||
absResult -= (dst_rep_t)(srcExpBias - dstExpBias) << dstSigBits;
|
||||
|
||||
const src_rep_t roundBits = aAbs & roundMask;
|
||||
// Round to nearest
|
||||
if (roundBits > halfway)
|
||||
absResult++;
|
||||
// Ties to even
|
||||
else if (roundBits == halfway)
|
||||
absResult += absResult & 1;
|
||||
}
|
||||
else if (aAbs > srcInfinity) {
|
||||
// a is NaN.
|
||||
// Conjure the result by beginning with infinity, setting the qNaN
|
||||
// bit and inserting the (truncated) trailing NaN field.
|
||||
absResult = (dst_rep_t)dstInfExp << dstSigBits;
|
||||
absResult |= dstQNaN;
|
||||
absResult |= ((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode;
|
||||
}
|
||||
else if (aAbs >= overflow) {
|
||||
// a overflows to infinity.
|
||||
absResult = (dst_rep_t)dstInfExp << dstSigBits;
|
||||
}
|
||||
else {
|
||||
// a underflows on conversion to the destination type or is an exact
|
||||
// zero. The result may be a denormal or zero. Extract the exponent
|
||||
// to get the shift amount for the denormalization.
|
||||
const int aExp = aAbs >> srcSigBits;
|
||||
const int shift = srcExpBias - dstExpBias - aExp + 1;
|
||||
|
||||
const src_rep_t significand = (aRep & srcSignificandMask) | srcMinNormal;
|
||||
|
||||
// Right shift by the denormalization amount with sticky.
|
||||
if (shift > srcSigBits) {
|
||||
absResult = 0;
|
||||
} else {
|
||||
const bool sticky = significand << (srcBits - shift);
|
||||
src_rep_t denormalizedSignificand = significand >> shift | sticky;
|
||||
absResult = denormalizedSignificand >> (srcSigBits - dstSigBits);
|
||||
const src_rep_t roundBits = denormalizedSignificand & roundMask;
|
||||
// Round to nearest
|
||||
if (roundBits > halfway)
|
||||
absResult++;
|
||||
// Ties to even
|
||||
else if (roundBits == halfway)
|
||||
absResult += absResult & 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the signbit to (dst_t)abs(a).
|
||||
const dst_rep_t result = absResult | sign >> (srcBits - dstBits);
|
||||
return dstFromRep(result);
|
||||
}
|
77
third_party/compiler_rt/fp_trunc_common.inc
vendored
Normal file
77
third_party/compiler_rt/fp_trunc_common.inc
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* clang-format off */
|
||||
//=== lib/fp_trunc.h - high precision -> low 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Set source and destination precision setting
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef FP_TRUNC_HEADER
|
||||
#define FP_TRUNC_HEADER
|
||||
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
#if defined SRC_SINGLE
|
||||
typedef float src_t;
|
||||
typedef uint32_t src_rep_t;
|
||||
#define SRC_REP_C UINT32_C
|
||||
static const int srcSigBits = 23;
|
||||
|
||||
#elif defined SRC_DOUBLE
|
||||
typedef double src_t;
|
||||
typedef uint64_t src_rep_t;
|
||||
#define SRC_REP_C UINT64_C
|
||||
static const int srcSigBits = 52;
|
||||
|
||||
#elif defined SRC_QUAD
|
||||
typedef long double src_t;
|
||||
typedef __uint128_t src_rep_t;
|
||||
#define SRC_REP_C (__uint128_t)
|
||||
static const int srcSigBits = 112;
|
||||
|
||||
#else
|
||||
#error Source should be double precision or quad precision!
|
||||
#endif //end source precision
|
||||
|
||||
#if defined DST_DOUBLE
|
||||
typedef double dst_t;
|
||||
typedef uint64_t dst_rep_t;
|
||||
#define DST_REP_C UINT64_C
|
||||
static const int dstSigBits = 52;
|
||||
|
||||
#elif defined DST_SINGLE
|
||||
typedef float dst_t;
|
||||
typedef uint32_t dst_rep_t;
|
||||
#define DST_REP_C UINT32_C
|
||||
static const int dstSigBits = 23;
|
||||
|
||||
#elif defined DST_HALF
|
||||
typedef uint16_t dst_t;
|
||||
typedef uint16_t dst_rep_t;
|
||||
#define DST_REP_C UINT16_C
|
||||
static const int dstSigBits = 10;
|
||||
|
||||
#else
|
||||
#error Destination should be single precision or double precision!
|
||||
#endif //end destination precision
|
||||
|
||||
// End of specialization parameters. Two helper routines for conversion to and
|
||||
// from the representation of floating-point data as integer values follow.
|
||||
|
||||
static __inline src_rep_t srcToRep(src_t x) {
|
||||
const union { src_t f; src_rep_t i; } rep = {.f = x};
|
||||
return rep.i;
|
||||
}
|
||||
|
||||
static __inline dst_t dstFromRep(dst_rep_t x) {
|
||||
const union { dst_t f; dst_rep_t i; } rep = {.i = x};
|
||||
return rep.f;
|
||||
}
|
||||
|
||||
#endif // FP_TRUNC_HEADER
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue