mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-08 13:53:54 +00:00
Import builtins from LLVM compiler-rt project
These are needed to provide division and modulo operations for the AArch32 target. This code is entirely unmodified. Imported from compiler-rt master branch as of May 4 2017. Change-Id: I001e1809f2afd4bf8d4cc3d2296798809f607144 Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
This commit is contained in:
parent
b4b541cb29
commit
0e14a7fbeb
10 changed files with 1160 additions and 0 deletions
91
lib/compiler-rt/LICENSE.TXT
Normal file
91
lib/compiler-rt/LICENSE.TXT
Normal file
|
@ -0,0 +1,91 @@
|
|||
==============================================================================
|
||||
compiler_rt License
|
||||
==============================================================================
|
||||
|
||||
The compiler_rt library is dual licensed under both the University of Illinois
|
||||
"BSD-Like" license and the MIT license. As a user of this code you may choose
|
||||
to use it under either license. As a contributor, you agree to allow your code
|
||||
to be used under both.
|
||||
|
||||
Full text of the relevant licenses is included below.
|
||||
|
||||
==============================================================================
|
||||
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2009-2016 by the contributors listed in 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.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in 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:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
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
|
||||
AUTHORS 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 IN
|
||||
THE SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
Copyrights and Licenses for Third Party Software Distributed with LLVM:
|
||||
==============================================================================
|
||||
The LLVM software contains code written by third parties. Such software will
|
||||
have its own individual LICENSE.TXT file in the directory in which it appears.
|
||||
This file will describe the copyrights, license, and restrictions which apply
|
||||
to that code.
|
||||
|
||||
The disclaimer of warranty in the University of Illinois Open Source License
|
||||
applies to all code in the LLVM Distribution, and nothing in any of the
|
||||
other licenses gives permission to use the names of the LLVM Team or the
|
||||
University of Illinois to endorse or promote products derived from this
|
||||
Software.
|
||||
|
46
lib/compiler-rt/builtins/arm/aeabi_uldivmod.S
Normal file
46
lib/compiler-rt/builtins/arm/aeabi_uldivmod.S
Normal file
|
@ -0,0 +1,46 @@
|
|||
//===-- aeabi_uldivmod.S - EABI uldivmod implementation -------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
// struct { uint64_t quot, uint64_t rem}
|
||||
// __aeabi_uldivmod(uint64_t numerator, uint64_t denominator) {
|
||||
// uint64_t rem, quot;
|
||||
// quot = __udivmoddi4(numerator, denominator, &rem);
|
||||
// return {quot, rem};
|
||||
// }
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
#define __aeabi_uldivmod __rt_udiv64
|
||||
#endif
|
||||
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
|
||||
push {r6, lr}
|
||||
sub sp, sp, #16
|
||||
add r6, sp, #8
|
||||
str r6, [sp]
|
||||
#if defined(__MINGW32__)
|
||||
movs r6, r0
|
||||
movs r0, r2
|
||||
movs r2, r6
|
||||
movs r6, r1
|
||||
movs r1, r3
|
||||
movs r3, r6
|
||||
#endif
|
||||
bl SYMBOL_NAME(__udivmoddi4)
|
||||
ldr r2, [sp, #8]
|
||||
ldr r3, [sp, #12]
|
||||
add sp, sp, #16
|
||||
pop {r6, pc}
|
||||
END_COMPILERRT_FUNCTION(__aeabi_uldivmod)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
169
lib/compiler-rt/builtins/assembly.h
Normal file
169
lib/compiler-rt/builtins/assembly.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
/* ===-- 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(__ANDROID__) || defined(__FreeBSD__)
|
||||
#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__)
|
||||
#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
|
||||
#define ARM_HAS_BX
|
||||
#endif
|
||||
#if !defined(__ARM_FEATURE_CLZ) && __ARM_ARCH_ISA_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 __ARM_ARCH_ISA_THUMB == 2
|
||||
#define IT(cond) it cond
|
||||
#define ITT(cond) itt cond
|
||||
#else
|
||||
#define IT(cond)
|
||||
#define ITT(cond)
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH_ISA_THUMB == 2
|
||||
#define WIDE(op) op.w
|
||||
#else
|
||||
#define WIDE(op) op
|
||||
#endif
|
||||
#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) \
|
||||
FILE_LEVEL_DIRECTIVE SEPARATOR \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
|
||||
DECLARE_SYMBOL_VISIBILITY(name) \
|
||||
SYMBOL_NAME(name):
|
||||
|
||||
#define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \
|
||||
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) \
|
||||
FILE_LEVEL_DIRECTIVE SEPARATOR \
|
||||
.globl SYMBOL_NAME(name) SEPARATOR \
|
||||
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
|
||||
HIDDEN(SYMBOL_NAME(name)) SEPARATOR \
|
||||
SYMBOL_NAME(name):
|
||||
|
||||
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
|
||||
.globl name SEPARATOR \
|
||||
SYMBOL_IS_FUNC(name) SEPARATOR \
|
||||
HIDDEN(name) SEPARATOR \
|
||||
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 */
|
116
lib/compiler-rt/builtins/int_endianness.h
Normal file
116
lib/compiler-rt/builtins/int_endianness.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
/* ===-- int_endianness.h - configuration header for compiler-rt ------------===
|
||||
*
|
||||
* 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 compiler-rt.
|
||||
* This file is not part of the interface of this library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef INT_ENDIANNESS_H
|
||||
#define INT_ENDIANNESS_H
|
||||
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
|
||||
defined(__ORDER_LITTLE_ENDIAN__)
|
||||
|
||||
/* Clang and GCC provide built-in endianness definitions. */
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define _YUGA_LITTLE_ENDIAN 0
|
||||
#define _YUGA_BIG_ENDIAN 1
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define _YUGA_LITTLE_ENDIAN 1
|
||||
#define _YUGA_BIG_ENDIAN 0
|
||||
#endif /* __BYTE_ORDER__ */
|
||||
|
||||
#else /* Compilers other than Clang or GCC. */
|
||||
|
||||
#if defined(__SVR4) && defined(__sun)
|
||||
#include <sys/byteorder.h>
|
||||
|
||||
#if defined(_BIG_ENDIAN)
|
||||
#define _YUGA_LITTLE_ENDIAN 0
|
||||
#define _YUGA_BIG_ENDIAN 1
|
||||
#elif defined(_LITTLE_ENDIAN)
|
||||
#define _YUGA_LITTLE_ENDIAN 1
|
||||
#define _YUGA_BIG_ENDIAN 0
|
||||
#else /* !_LITTLE_ENDIAN */
|
||||
#error "unknown endianness"
|
||||
#endif /* !_LITTLE_ENDIAN */
|
||||
|
||||
#endif /* Solaris and AuroraUX. */
|
||||
|
||||
/* .. */
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
|
||||
defined(__minix)
|
||||
#include <sys/endian.h>
|
||||
|
||||
#if _BYTE_ORDER == _BIG_ENDIAN
|
||||
#define _YUGA_LITTLE_ENDIAN 0
|
||||
#define _YUGA_BIG_ENDIAN 1
|
||||
#elif _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
#define _YUGA_LITTLE_ENDIAN 1
|
||||
#define _YUGA_BIG_ENDIAN 0
|
||||
#endif /* _BYTE_ORDER */
|
||||
|
||||
#endif /* *BSD */
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__Bitrig__)
|
||||
#include <machine/endian.h>
|
||||
|
||||
#if _BYTE_ORDER == _BIG_ENDIAN
|
||||
#define _YUGA_LITTLE_ENDIAN 0
|
||||
#define _YUGA_BIG_ENDIAN 1
|
||||
#elif _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
#define _YUGA_LITTLE_ENDIAN 1
|
||||
#define _YUGA_BIG_ENDIAN 0
|
||||
#endif /* _BYTE_ORDER */
|
||||
|
||||
#endif /* OpenBSD and Bitrig. */
|
||||
|
||||
/* .. */
|
||||
|
||||
/* Mac OSX has __BIG_ENDIAN__ or __LITTLE_ENDIAN__ automatically set by the
|
||||
* compiler (at least with GCC) */
|
||||
#if defined(__APPLE__) || defined(__ellcc__ )
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#if __BIG_ENDIAN__
|
||||
#define _YUGA_LITTLE_ENDIAN 0
|
||||
#define _YUGA_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif /* __BIG_ENDIAN__ */
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#if __LITTLE_ENDIAN__
|
||||
#define _YUGA_LITTLE_ENDIAN 1
|
||||
#define _YUGA_BIG_ENDIAN 0
|
||||
#endif
|
||||
#endif /* __LITTLE_ENDIAN__ */
|
||||
|
||||
#endif /* Mac OSX */
|
||||
|
||||
/* .. */
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#define _YUGA_LITTLE_ENDIAN 1
|
||||
#define _YUGA_BIG_ENDIAN 0
|
||||
|
||||
#endif /* Windows */
|
||||
|
||||
#endif /* Clang or GCC. */
|
||||
|
||||
/* . */
|
||||
|
||||
#if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN)
|
||||
#error Unable to determine endian
|
||||
#endif /* Check we found an endianness correctly. */
|
||||
|
||||
#endif /* INT_ENDIANNESS_H */
|
133
lib/compiler-rt/builtins/int_lib.h
Normal file
133
lib/compiler-rt/builtins/int_lib.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* ===-- int_lib.h - configuration header for compiler-rt -----------------===
|
||||
*
|
||||
* 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 compiler-rt.
|
||||
* This file is not part of the interface of this library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef INT_LIB_H
|
||||
#define INT_LIB_H
|
||||
|
||||
/* Assumption: Signed integral is 2's complement. */
|
||||
/* Assumption: Right shift of signed negative is arithmetic shift. */
|
||||
/* Assumption: Endianness is little or big (not mixed). */
|
||||
|
||||
#if defined(__ELF__)
|
||||
#define FNALIAS(alias_name, original_name) \
|
||||
void alias_name() __attribute__((alias(#original_name)))
|
||||
#else
|
||||
#define FNALIAS(alias, name) _Pragma("GCC error(\"alias unsupported on this file format\")")
|
||||
#endif
|
||||
|
||||
/* ABI macro definitions */
|
||||
|
||||
#if __ARM_EABI__
|
||||
# define ARM_EABI_FNALIAS(aeabi_name, name) \
|
||||
void __aeabi_##aeabi_name() __attribute__((alias("__" #name)));
|
||||
# ifdef COMPILER_RT_ARMHF_TARGET
|
||||
# define COMPILER_RT_ABI
|
||||
# else
|
||||
# define COMPILER_RT_ABI __attribute__((pcs("aapcs")))
|
||||
# endif
|
||||
#else
|
||||
# define ARM_EABI_FNALIAS(aeabi_name, name)
|
||||
# define COMPILER_RT_ABI
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define ALWAYS_INLINE __forceinline
|
||||
#define NOINLINE __declspec(noinline)
|
||||
#define NORETURN __declspec(noreturn)
|
||||
#define UNUSED
|
||||
#else
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define UNUSED __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE))
|
||||
/*
|
||||
* Kernel and boot environment can't use normal headers,
|
||||
* so use the equivalent system headers.
|
||||
*/
|
||||
# include <machine/limits.h>
|
||||
# include <sys/stdint.h>
|
||||
# include <sys/types.h>
|
||||
#else
|
||||
/* Include the standard compiler builtin headers we use functionality from. */
|
||||
# include <limits.h>
|
||||
# include <stdint.h>
|
||||
# include <stdbool.h>
|
||||
# include <float.h>
|
||||
#endif
|
||||
|
||||
/* Include the commonly used internal type definitions. */
|
||||
#include "int_types.h"
|
||||
|
||||
/* Include internal utility function declarations. */
|
||||
#include "int_util.h"
|
||||
|
||||
COMPILER_RT_ABI si_int __paritysi2(si_int a);
|
||||
COMPILER_RT_ABI si_int __paritydi2(di_int a);
|
||||
|
||||
COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b);
|
||||
COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b);
|
||||
COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d);
|
||||
|
||||
COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int* rem);
|
||||
COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
|
||||
#ifdef CRT_HAS_128BIT
|
||||
COMPILER_RT_ABI si_int __clzti2(ti_int a);
|
||||
COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
|
||||
#endif
|
||||
|
||||
/* Definitions for builtins unavailable on MSVC */
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#include <intrin.h>
|
||||
|
||||
uint32_t __inline __builtin_ctz(uint32_t value) {
|
||||
unsigned long trailing_zero = 0;
|
||||
if (_BitScanForward(&trailing_zero, value))
|
||||
return trailing_zero;
|
||||
return 32;
|
||||
}
|
||||
|
||||
uint32_t __inline __builtin_clz(uint32_t value) {
|
||||
unsigned long leading_zero = 0;
|
||||
if (_BitScanReverse(&leading_zero, value))
|
||||
return 31 - leading_zero;
|
||||
return 32;
|
||||
}
|
||||
|
||||
#if defined(_M_ARM) || defined(_M_X64)
|
||||
uint32_t __inline __builtin_clzll(uint64_t value) {
|
||||
unsigned long leading_zero = 0;
|
||||
if (_BitScanReverse64(&leading_zero, value))
|
||||
return 63 - leading_zero;
|
||||
return 64;
|
||||
}
|
||||
#else
|
||||
uint32_t __inline __builtin_clzll(uint64_t value) {
|
||||
if (value == 0)
|
||||
return 64;
|
||||
uint32_t msh = (uint32_t)(value >> 32);
|
||||
uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);
|
||||
if (msh != 0)
|
||||
return __builtin_clz(msh);
|
||||
return 32 + __builtin_clz(lsh);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define __builtin_clzl __builtin_clzll
|
||||
#endif /* defined(_MSC_VER) && !defined(__clang__) */
|
||||
|
||||
#endif /* INT_LIB_H */
|
114
lib/compiler-rt/builtins/int_math.h
Normal file
114
lib/compiler-rt/builtins/int_math.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* ===-- int_math.h - internal math inlines ---------------------------------===
|
||||
*
|
||||
* 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 not part of the interface of this library.
|
||||
*
|
||||
* This file defines substitutes for the libm functions used in some of the
|
||||
* compiler-rt implementations, defined in such a way that there is not a direct
|
||||
* dependency on libm or math.h. Instead, we use the compiler builtin versions
|
||||
* where available. This reduces our dependencies on the system SDK by foisting
|
||||
* the responsibility onto the compiler.
|
||||
*
|
||||
* ===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef INT_MATH_H
|
||||
#define INT_MATH_H
|
||||
|
||||
#ifndef __has_builtin
|
||||
# define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <ymath.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define CRT_INFINITY INFINITY
|
||||
#else
|
||||
#define CRT_INFINITY __builtin_huge_valf()
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define crt_isfinite(x) _finite((x))
|
||||
#define crt_isinf(x) !_finite((x))
|
||||
#define crt_isnan(x) _isnan((x))
|
||||
#else
|
||||
/* Define crt_isfinite in terms of the builtin if available, otherwise provide
|
||||
* an alternate version in terms of our other functions. This supports some
|
||||
* versions of GCC which didn't have __builtin_isfinite.
|
||||
*/
|
||||
#if __has_builtin(__builtin_isfinite)
|
||||
# define crt_isfinite(x) __builtin_isfinite((x))
|
||||
#elif defined(__GNUC__)
|
||||
# define crt_isfinite(x) \
|
||||
__extension__(({ \
|
||||
__typeof((x)) x_ = (x); \
|
||||
!crt_isinf(x_) && !crt_isnan(x_); \
|
||||
}))
|
||||
#else
|
||||
# error "Do not know how to check for infinity"
|
||||
#endif /* __has_builtin(__builtin_isfinite) */
|
||||
#define crt_isinf(x) __builtin_isinf((x))
|
||||
#define crt_isnan(x) __builtin_isnan((x))
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define crt_copysign(x, y) copysign((x), (y))
|
||||
#define crt_copysignf(x, y) copysignf((x), (y))
|
||||
#define crt_copysignl(x, y) copysignl((x), (y))
|
||||
#else
|
||||
#define crt_copysign(x, y) __builtin_copysign((x), (y))
|
||||
#define crt_copysignf(x, y) __builtin_copysignf((x), (y))
|
||||
#define crt_copysignl(x, y) __builtin_copysignl((x), (y))
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define crt_fabs(x) fabs((x))
|
||||
#define crt_fabsf(x) fabsf((x))
|
||||
#define crt_fabsl(x) fabs((x))
|
||||
#else
|
||||
#define crt_fabs(x) __builtin_fabs((x))
|
||||
#define crt_fabsf(x) __builtin_fabsf((x))
|
||||
#define crt_fabsl(x) __builtin_fabsl((x))
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define crt_fmax(x, y) __max((x), (y))
|
||||
#define crt_fmaxf(x, y) __max((x), (y))
|
||||
#define crt_fmaxl(x, y) __max((x), (y))
|
||||
#else
|
||||
#define crt_fmax(x, y) __builtin_fmax((x), (y))
|
||||
#define crt_fmaxf(x, y) __builtin_fmaxf((x), (y))
|
||||
#define crt_fmaxl(x, y) __builtin_fmaxl((x), (y))
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define crt_logb(x) logb((x))
|
||||
#define crt_logbf(x) logbf((x))
|
||||
#define crt_logbl(x) logbl((x))
|
||||
#else
|
||||
#define crt_logb(x) __builtin_logb((x))
|
||||
#define crt_logbf(x) __builtin_logbf((x))
|
||||
#define crt_logbl(x) __builtin_logbl((x))
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define crt_scalbn(x, y) scalbn((x), (y))
|
||||
#define crt_scalbnf(x, y) scalbnf((x), (y))
|
||||
#define crt_scalbnl(x, y) scalbnl((x), (y))
|
||||
#else
|
||||
#define crt_scalbn(x, y) __builtin_scalbn((x), (y))
|
||||
#define crt_scalbnf(x, y) __builtin_scalbnf((x), (y))
|
||||
#define crt_scalbnl(x, y) __builtin_scalbnl((x), (y))
|
||||
#endif
|
||||
|
||||
#endif /* INT_MATH_H */
|
166
lib/compiler-rt/builtins/int_types.h
Normal file
166
lib/compiler-rt/builtins/int_types.h
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* ===-- int_lib.h - configuration header for compiler-rt -----------------===
|
||||
*
|
||||
* 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 not part of the interface of this library.
|
||||
*
|
||||
* This file defines various standard types, most importantly a number of unions
|
||||
* used to access parts of larger types.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef INT_TYPES_H
|
||||
#define INT_TYPES_H
|
||||
|
||||
#include "int_endianness.h"
|
||||
|
||||
/* si_int is defined in Linux sysroot's asm-generic/siginfo.h */
|
||||
#ifdef si_int
|
||||
#undef si_int
|
||||
#endif
|
||||
typedef int si_int;
|
||||
typedef unsigned su_int;
|
||||
|
||||
typedef long long di_int;
|
||||
typedef unsigned long long du_int;
|
||||
|
||||
typedef union
|
||||
{
|
||||
di_int all;
|
||||
struct
|
||||
{
|
||||
#if _YUGA_LITTLE_ENDIAN
|
||||
su_int low;
|
||||
si_int high;
|
||||
#else
|
||||
si_int high;
|
||||
su_int low;
|
||||
#endif /* _YUGA_LITTLE_ENDIAN */
|
||||
}s;
|
||||
} dwords;
|
||||
|
||||
typedef union
|
||||
{
|
||||
du_int all;
|
||||
struct
|
||||
{
|
||||
#if _YUGA_LITTLE_ENDIAN
|
||||
su_int low;
|
||||
su_int high;
|
||||
#else
|
||||
su_int high;
|
||||
su_int low;
|
||||
#endif /* _YUGA_LITTLE_ENDIAN */
|
||||
}s;
|
||||
} udwords;
|
||||
|
||||
/* MIPS64 issue: PR 20098 */
|
||||
#if (defined(__LP64__) || defined(__wasm__)) && \
|
||||
!(defined(__mips__) && defined(__clang__))
|
||||
#define CRT_HAS_128BIT
|
||||
#endif
|
||||
|
||||
#ifdef CRT_HAS_128BIT
|
||||
typedef int ti_int __attribute__ ((mode (TI)));
|
||||
typedef unsigned tu_int __attribute__ ((mode (TI)));
|
||||
|
||||
typedef union
|
||||
{
|
||||
ti_int all;
|
||||
struct
|
||||
{
|
||||
#if _YUGA_LITTLE_ENDIAN
|
||||
du_int low;
|
||||
di_int high;
|
||||
#else
|
||||
di_int high;
|
||||
du_int low;
|
||||
#endif /* _YUGA_LITTLE_ENDIAN */
|
||||
}s;
|
||||
} twords;
|
||||
|
||||
typedef union
|
||||
{
|
||||
tu_int all;
|
||||
struct
|
||||
{
|
||||
#if _YUGA_LITTLE_ENDIAN
|
||||
du_int low;
|
||||
du_int high;
|
||||
#else
|
||||
du_int high;
|
||||
du_int low;
|
||||
#endif /* _YUGA_LITTLE_ENDIAN */
|
||||
}s;
|
||||
} utwords;
|
||||
|
||||
static __inline ti_int make_ti(di_int h, di_int l) {
|
||||
twords r;
|
||||
r.s.high = h;
|
||||
r.s.low = l;
|
||||
return r.all;
|
||||
}
|
||||
|
||||
static __inline tu_int make_tu(du_int h, du_int l) {
|
||||
utwords r;
|
||||
r.s.high = h;
|
||||
r.s.low = l;
|
||||
return r.all;
|
||||
}
|
||||
|
||||
#endif /* CRT_HAS_128BIT */
|
||||
|
||||
typedef union
|
||||
{
|
||||
su_int u;
|
||||
float f;
|
||||
} float_bits;
|
||||
|
||||
typedef union
|
||||
{
|
||||
udwords u;
|
||||
double f;
|
||||
} double_bits;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if _YUGA_LITTLE_ENDIAN
|
||||
udwords low;
|
||||
udwords high;
|
||||
#else
|
||||
udwords high;
|
||||
udwords low;
|
||||
#endif /* _YUGA_LITTLE_ENDIAN */
|
||||
} uqwords;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uqwords u;
|
||||
long double f;
|
||||
} long_double_bits;
|
||||
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
typedef float _Complex Fcomplex;
|
||||
typedef double _Complex Dcomplex;
|
||||
typedef long double _Complex Lcomplex;
|
||||
|
||||
#define COMPLEX_REAL(x) __real__(x)
|
||||
#define COMPLEX_IMAGINARY(x) __imag__(x)
|
||||
#else
|
||||
typedef struct { float real, imaginary; } Fcomplex;
|
||||
|
||||
typedef struct { double real, imaginary; } Dcomplex;
|
||||
|
||||
typedef struct { long double real, imaginary; } Lcomplex;
|
||||
|
||||
#define COMPLEX_REAL(x) (x).real
|
||||
#define COMPLEX_IMAGINARY(x) (x).imaginary
|
||||
#endif
|
||||
#endif /* INT_TYPES_H */
|
||||
|
61
lib/compiler-rt/builtins/int_util.c
Normal file
61
lib/compiler-rt/builtins/int_util.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* ===-- int_util.c - Implement internal utilities --------------------------===
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
#include "int_util.h"
|
||||
|
||||
/* NOTE: The definitions in this file are declared weak because we clients to be
|
||||
* able to arbitrarily package individual functions into separate .a files. If
|
||||
* we did not declare these weak, some link situations might end up seeing
|
||||
* duplicate strong definitions of the same symbol.
|
||||
*
|
||||
* We can't use this solution for kernel use (which may not support weak), but
|
||||
* currently expect that when built for kernel use all the functionality is
|
||||
* packaged into a single library.
|
||||
*/
|
||||
|
||||
#ifdef KERNEL_USE
|
||||
|
||||
NORETURN extern void panic(const char *, ...);
|
||||
#ifndef _WIN32
|
||||
__attribute__((visibility("hidden")))
|
||||
#endif
|
||||
void compilerrt_abort_impl(const char *file, int line, const char *function) {
|
||||
panic("%s:%d: abort in %s", file, line, function);
|
||||
}
|
||||
|
||||
#elif __APPLE__
|
||||
|
||||
/* from libSystem.dylib */
|
||||
NORETURN extern void __assert_rtn(const char *func, const char *file, int line,
|
||||
const char *message);
|
||||
|
||||
#ifndef _WIN32
|
||||
__attribute__((weak))
|
||||
__attribute__((visibility("hidden")))
|
||||
#endif
|
||||
void compilerrt_abort_impl(const char *file, int line, const char *function) {
|
||||
__assert_rtn(function, file, line, "libcompiler_rt abort");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Get the system definition of abort() */
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
__attribute__((weak))
|
||||
__attribute__((visibility("hidden")))
|
||||
#endif
|
||||
void compilerrt_abort_impl(const char *file, int line, const char *function) {
|
||||
abort();
|
||||
}
|
||||
|
||||
#endif
|
33
lib/compiler-rt/builtins/int_util.h
Normal file
33
lib/compiler-rt/builtins/int_util.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* ===-- int_util.h - internal utility functions ----------------------------===
|
||||
*
|
||||
* 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 not part of the interface of this library.
|
||||
*
|
||||
* This file defines non-inline utilities which are available for use in the
|
||||
* library. The function definitions themselves are all contained in int_util.c
|
||||
* which will always be compiled into any compiler-rt library.
|
||||
*
|
||||
* ===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef INT_UTIL_H
|
||||
#define INT_UTIL_H
|
||||
|
||||
/** \brief Trigger a program abort (or panic for kernel code). */
|
||||
#define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, __func__)
|
||||
|
||||
NORETURN void compilerrt_abort_impl(const char *file, int line,
|
||||
const char *function);
|
||||
|
||||
#define COMPILE_TIME_ASSERT(expr) COMPILE_TIME_ASSERT1(expr, __COUNTER__)
|
||||
#define COMPILE_TIME_ASSERT1(expr, cnt) COMPILE_TIME_ASSERT2(expr, cnt)
|
||||
#define COMPILE_TIME_ASSERT2(expr, cnt) \
|
||||
typedef char ct_assert_##cnt[(expr) ? 1 : -1] UNUSED
|
||||
|
||||
#endif /* INT_UTIL_H */
|
231
lib/compiler-rt/builtins/udivmoddi4.c
Normal file
231
lib/compiler-rt/builtins/udivmoddi4.c
Normal file
|
@ -0,0 +1,231 @@
|
|||
/* ===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------===
|
||||
*
|
||||
* 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 __udivmoddi4 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Effects: if rem != 0, *rem = a % b
|
||||
* Returns: a / b
|
||||
*/
|
||||
|
||||
/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__udivmoddi4(du_int a, du_int b, du_int* rem)
|
||||
{
|
||||
const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;
|
||||
const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
|
||||
udwords n;
|
||||
n.all = a;
|
||||
udwords d;
|
||||
d.all = b;
|
||||
udwords q;
|
||||
udwords r;
|
||||
unsigned sr;
|
||||
/* special cases, X is unknown, K != 0 */
|
||||
if (n.s.high == 0)
|
||||
{
|
||||
if (d.s.high == 0)
|
||||
{
|
||||
/* 0 X
|
||||
* ---
|
||||
* 0 X
|
||||
*/
|
||||
if (rem)
|
||||
*rem = n.s.low % d.s.low;
|
||||
return n.s.low / d.s.low;
|
||||
}
|
||||
/* 0 X
|
||||
* ---
|
||||
* K X
|
||||
*/
|
||||
if (rem)
|
||||
*rem = n.s.low;
|
||||
return 0;
|
||||
}
|
||||
/* n.s.high != 0 */
|
||||
if (d.s.low == 0)
|
||||
{
|
||||
if (d.s.high == 0)
|
||||
{
|
||||
/* K X
|
||||
* ---
|
||||
* 0 0
|
||||
*/
|
||||
if (rem)
|
||||
*rem = n.s.high % d.s.low;
|
||||
return n.s.high / d.s.low;
|
||||
}
|
||||
/* d.s.high != 0 */
|
||||
if (n.s.low == 0)
|
||||
{
|
||||
/* K 0
|
||||
* ---
|
||||
* K 0
|
||||
*/
|
||||
if (rem)
|
||||
{
|
||||
r.s.high = n.s.high % d.s.high;
|
||||
r.s.low = 0;
|
||||
*rem = r.all;
|
||||
}
|
||||
return n.s.high / d.s.high;
|
||||
}
|
||||
/* K K
|
||||
* ---
|
||||
* K 0
|
||||
*/
|
||||
if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */
|
||||
{
|
||||
if (rem)
|
||||
{
|
||||
r.s.low = n.s.low;
|
||||
r.s.high = n.s.high & (d.s.high - 1);
|
||||
*rem = r.all;
|
||||
}
|
||||
return n.s.high >> __builtin_ctz(d.s.high);
|
||||
}
|
||||
/* K K
|
||||
* ---
|
||||
* K 0
|
||||
*/
|
||||
sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high);
|
||||
/* 0 <= sr <= n_uword_bits - 2 or sr large */
|
||||
if (sr > n_uword_bits - 2)
|
||||
{
|
||||
if (rem)
|
||||
*rem = n.all;
|
||||
return 0;
|
||||
}
|
||||
++sr;
|
||||
/* 1 <= sr <= n_uword_bits - 1 */
|
||||
/* q.all = n.all << (n_udword_bits - sr); */
|
||||
q.s.low = 0;
|
||||
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||
/* r.all = n.all >> sr; */
|
||||
r.s.high = n.s.high >> sr;
|
||||
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||
}
|
||||
else /* d.s.low != 0 */
|
||||
{
|
||||
if (d.s.high == 0)
|
||||
{
|
||||
/* K X
|
||||
* ---
|
||||
* 0 K
|
||||
*/
|
||||
if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */
|
||||
{
|
||||
if (rem)
|
||||
*rem = n.s.low & (d.s.low - 1);
|
||||
if (d.s.low == 1)
|
||||
return n.all;
|
||||
sr = __builtin_ctz(d.s.low);
|
||||
q.s.high = n.s.high >> sr;
|
||||
q.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||
return q.all;
|
||||
}
|
||||
/* K X
|
||||
* ---
|
||||
* 0 K
|
||||
*/
|
||||
sr = 1 + n_uword_bits + __builtin_clz(d.s.low) - __builtin_clz(n.s.high);
|
||||
/* 2 <= sr <= n_udword_bits - 1
|
||||
* q.all = n.all << (n_udword_bits - sr);
|
||||
* r.all = n.all >> sr;
|
||||
*/
|
||||
if (sr == n_uword_bits)
|
||||
{
|
||||
q.s.low = 0;
|
||||
q.s.high = n.s.low;
|
||||
r.s.high = 0;
|
||||
r.s.low = n.s.high;
|
||||
}
|
||||
else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1
|
||||
{
|
||||
q.s.low = 0;
|
||||
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||
r.s.high = n.s.high >> sr;
|
||||
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||
}
|
||||
else // n_uword_bits + 1 <= sr <= n_udword_bits - 1
|
||||
{
|
||||
q.s.low = n.s.low << (n_udword_bits - sr);
|
||||
q.s.high = (n.s.high << (n_udword_bits - sr)) |
|
||||
(n.s.low >> (sr - n_uword_bits));
|
||||
r.s.high = 0;
|
||||
r.s.low = n.s.high >> (sr - n_uword_bits);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* K X
|
||||
* ---
|
||||
* K K
|
||||
*/
|
||||
sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high);
|
||||
/* 0 <= sr <= n_uword_bits - 1 or sr large */
|
||||
if (sr > n_uword_bits - 1)
|
||||
{
|
||||
if (rem)
|
||||
*rem = n.all;
|
||||
return 0;
|
||||
}
|
||||
++sr;
|
||||
/* 1 <= sr <= n_uword_bits */
|
||||
/* q.all = n.all << (n_udword_bits - sr); */
|
||||
q.s.low = 0;
|
||||
if (sr == n_uword_bits)
|
||||
{
|
||||
q.s.high = n.s.low;
|
||||
r.s.high = 0;
|
||||
r.s.low = n.s.high;
|
||||
}
|
||||
else
|
||||
{
|
||||
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||
r.s.high = n.s.high >> sr;
|
||||
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Not a special case
|
||||
* q and r are initialized with:
|
||||
* q.all = n.all << (n_udword_bits - sr);
|
||||
* r.all = n.all >> sr;
|
||||
* 1 <= sr <= n_udword_bits - 1
|
||||
*/
|
||||
su_int carry = 0;
|
||||
for (; sr > 0; --sr)
|
||||
{
|
||||
/* r:q = ((r:q) << 1) | carry */
|
||||
r.s.high = (r.s.high << 1) | (r.s.low >> (n_uword_bits - 1));
|
||||
r.s.low = (r.s.low << 1) | (q.s.high >> (n_uword_bits - 1));
|
||||
q.s.high = (q.s.high << 1) | (q.s.low >> (n_uword_bits - 1));
|
||||
q.s.low = (q.s.low << 1) | carry;
|
||||
/* carry = 0;
|
||||
* if (r.all >= d.all)
|
||||
* {
|
||||
* r.all -= d.all;
|
||||
* carry = 1;
|
||||
* }
|
||||
*/
|
||||
const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1);
|
||||
carry = s & 1;
|
||||
r.all -= d.all & s;
|
||||
}
|
||||
q.all = (q.all << 1) | carry;
|
||||
if (rem)
|
||||
*rem = r.all;
|
||||
return q.all;
|
||||
}
|
Loading…
Add table
Reference in a new issue