GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -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.
@@ -0,0 +1,45 @@
//===-- aeabi_ldivmod.S - EABI ldivmod implementation ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "../assembly.h"
// struct { int64_t quot, int64_t rem}
// __aeabi_ldivmod(int64_t numerator, int64_t denominator) {
// int64_t rem, quot;
// quot = __divmoddi4(numerator, denominator, &rem);
// return {quot, rem};
// }
#if defined(__MINGW32__)
#define __aeabi_ldivmod __rt_sdiv64
#endif
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
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(__divmoddi4)
ldr r2, [sp, #8]
ldr r3, [sp, #12]
add sp, sp, #16
pop {r6, pc}
END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
NO_EXEC_STACK_DIRECTIVE
@@ -0,0 +1,29 @@
//===-- aeabi_memcpy.S - EABI memcpy implementation -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "../assembly.h"
// void __aeabi_memcpy(void *dest, void *src, size_t n) { memcpy(dest, src, n); }
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_memcpy)
#ifdef USE_THUMB_1
push {r7, lr}
bl memcpy
pop {r7, pc}
#else
b memcpy
#endif
END_COMPILERRT_FUNCTION(__aeabi_memcpy)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy)
NO_EXEC_STACK_DIRECTIVE
@@ -0,0 +1,49 @@
//===-- aeabi_memset.S - EABI memset implementation -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "../assembly.h"
// void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n); }
// void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0); }
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_memset)
mov r3, r1
mov r1, r2
mov r2, r3
#ifdef USE_THUMB_1
push {r7, lr}
bl memset
pop {r7, pc}
#else
b memset
#endif
END_COMPILERRT_FUNCTION(__aeabi_memset)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset4, __aeabi_memset)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset)
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_memclr)
mov r2, r1
movs r1, #0
#ifdef USE_THUMB_1
push {r7, lr}
bl memset
pop {r7, pc}
#else
b memset
#endif
END_COMPILERRT_FUNCTION(__aeabi_memclr)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
NO_EXEC_STACK_DIRECTIVE
@@ -0,0 +1,45 @@
//===-- aeabi_uldivmod.S - EABI uldivmod implementation -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#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
@@ -0,0 +1,292 @@
//===-- assembly.h - compiler-rt assembler support macros -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file 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(__linux__) && defined(__CET__)
#if __has_include(<cet.h>)
#include <cet.h>
#endif
#endif
#if defined(__APPLE__) && defined(__aarch64__)
#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__) || defined(__aarch64__)
#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__) || defined(__aarch64__)
#define FUNC_ALIGN \
.text SEPARATOR \
.balign 16 SEPARATOR
#else
#define FUNC_ALIGN
#endif
// BTI and PAC gnu property note
#define NT_GNU_PROPERTY_TYPE_0 5
#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1
#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2
#if defined(__ARM_FEATURE_BTI_DEFAULT)
#define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI
#else
#define BTI_FLAG 0
#endif
#if __ARM_FEATURE_PAC_DEFAULT & 3
#define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC
#else
#define PAC_FLAG 0
#endif
#define GNU_PROPERTY(type, value) \
.pushsection .note.gnu.property, "a" SEPARATOR \
.p2align 3 SEPARATOR \
.word 4 SEPARATOR \
.word 16 SEPARATOR \
.word NT_GNU_PROPERTY_TYPE_0 SEPARATOR \
.asciz "GNU" SEPARATOR \
.word type SEPARATOR \
.word 4 SEPARATOR \
.word value SEPARATOR \
.word 0 SEPARATOR \
.popsection
#if BTI_FLAG != 0
#define BTI_C hint #34
#define BTI_J hint #36
#else
#define BTI_C
#define BTI_J
#endif
#if (BTI_FLAG | PAC_FLAG) != 0
#define GNU_PROPERTY_BTI_PAC \
GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, BTI_FLAG | PAC_FLAG)
#else
#define GNU_PROPERTY_BTI_PAC
#endif
#if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM)
#define CFI_START .cfi_startproc
#define CFI_END .cfi_endproc
#else
#define CFI_START
#define CFI_END
#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 GLUE2(a, b) GLUE2_(a, b)
#define GLUE3_(a, b, c) a##b##c
#define GLUE3(a, b, c) GLUE3_(a, b, c)
#define GLUE4_(a, b, c, d) a##b##c##d
#define GLUE4(a, b, c, d) GLUE4_(a, b, c, d)
#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
#ifdef VISIBILITY_HIDDEN
#define DECLARE_SYMBOL_VISIBILITY(name) \
HIDDEN(SYMBOL_NAME(name)) SEPARATOR
#define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \
HIDDEN(name) SEPARATOR
#else
#define DECLARE_SYMBOL_VISIBILITY(name)
#define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(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_OUTLINE_FUNCTION_UNMANGLED(name) \
DEFINE_CODE_STATE \
FUNC_ALIGN \
.globl name SEPARATOR \
SYMBOL_IS_FUNC(name) SEPARATOR \
DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR \
CFI_START SEPARATOR \
DECLARE_FUNC_ENCODING \
name: SEPARATOR BTI_C
#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)
#define END_COMPILERRT_OUTLINE_FUNCTION(name) \
CFI_END SEPARATOR \
.size SYMBOL_NAME(name), . - SYMBOL_NAME(name)
#else
#define END_COMPILERRT_FUNCTION(name)
#define END_COMPILERRT_OUTLINE_FUNCTION(name) \
CFI_END
#endif
#endif // COMPILERRT_ASSEMBLY_H
@@ -0,0 +1,35 @@
//===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements __ctzdi2 for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "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 int __ctzsi2(si_int);
#endif
// Precondition: a != 0
COMPILER_RT_ABI int __ctzdi2(di_int a) {
dwords x;
x.all = a;
const si_int f = -(x.s.low == 0);
return ctzsi((x.s.high & f) | (x.s.low & ~f)) +
(f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
}
@@ -0,0 +1,22 @@
//===-- divdi3.c - Implement __divdi3 -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements __divdi3 for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
// Returns: a / b
#define fixint_t di_int
#define fixuint_t du_int
#define COMPUTE_UDIV(a, b) __udivmoddi4((a), (b), (du_int *)0)
#include "int_div_impl.inc"
COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b) { return __divXi3(a, b); }
@@ -0,0 +1,28 @@
//===-- divmoddi4.c - Implement __divmoddi4 -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements __divmoddi4 for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
// Returns: a / b, *rem = a % b
COMPILER_RT_ABI di_int __divmoddi4(di_int a, di_int b, di_int *rem) {
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_b ^= s_a; // sign of quotient
du_int r;
di_int q = (__udivmoddi4(a, b, &r) ^ s_b) - s_b; // negate if s_b == -1
*rem = (r ^ s_a) - s_a; // negate if s_a == -1
return q;
}
@@ -0,0 +1,95 @@
//===-- int_div_impl.inc - Integer division ---------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Helpers used by __udivsi3, __umodsi3, __udivdi3, and __umodsi3.
//
//===----------------------------------------------------------------------===//
#define clz(a) (sizeof(a) == sizeof(unsigned long long) ? __builtin_clzll(a) : clzsi(a))
// Adapted from Figure 3-40 of The PowerPC Compiler Writer's Guide
static __inline fixuint_t __udivXi3(fixuint_t n, fixuint_t d) {
const unsigned N = sizeof(fixuint_t) * CHAR_BIT;
// d == 0 cases are unspecified.
unsigned sr = (d ? clz(d) : N) - (n ? clz(n) : N);
// 0 <= sr <= N - 1 or sr is very large.
if (sr > N - 1) // n < d
return 0;
if (sr == N - 1) // d == 1
return n;
++sr;
// 1 <= sr <= N - 1. Shifts do not trigger UB.
fixuint_t r = n >> sr;
n <<= N - sr;
fixuint_t carry = 0;
for (; sr > 0; --sr) {
r = (r << 1) | (n >> (N - 1));
n = (n << 1) | carry;
// Branch-less version of:
// carry = 0;
// if (r >= d) r -= d, carry = 1;
const fixint_t s = (fixint_t)(d - r - 1) >> (N - 1);
carry = s & 1;
r -= d & s;
}
n = (n << 1) | carry;
return n;
}
// Mostly identical to __udivXi3 but the return values are different.
static __inline fixuint_t __umodXi3(fixuint_t n, fixuint_t d) {
const unsigned N = sizeof(fixuint_t) * CHAR_BIT;
// d == 0 cases are unspecified.
unsigned sr = (d ? clz(d) : N) - (n ? clz(n) : N);
// 0 <= sr <= N - 1 or sr is very large.
if (sr > N - 1) // n < d
return n;
if (sr == N - 1) // d == 1
return 0;
++sr;
// 1 <= sr <= N - 1. Shifts do not trigger UB.
fixuint_t r = n >> sr;
n <<= N - sr;
fixuint_t carry = 0;
for (; sr > 0; --sr) {
r = (r << 1) | (n >> (N - 1));
n = (n << 1) | carry;
// Branch-less version of:
// carry = 0;
// if (r >= d) r -= d, carry = 1;
const fixint_t s = (fixint_t)(d - r - 1) >> (N - 1);
carry = s & 1;
r -= d & s;
}
return r;
}
#ifdef COMPUTE_UDIV
static __inline fixint_t __divXi3(fixint_t a, fixint_t b) {
const int N = (int)(sizeof(fixint_t) * CHAR_BIT) - 1;
fixint_t s_a = a >> N; // s_a = a < 0 ? -1 : 0
fixint_t s_b = b >> N; // s_b = b < 0 ? -1 : 0
fixuint_t a_u = (fixuint_t)(a ^ s_a) + (-s_a); // negate if s_a == -1
fixuint_t b_u = (fixuint_t)(b ^ s_b) + (-s_b); // negate if s_b == -1
s_a ^= s_b; // sign of quotient
return (COMPUTE_UDIV(a_u, b_u) ^ s_a) + (-s_a); // negate if s_a == -1
}
#endif // COMPUTE_UDIV
#ifdef ASSIGN_UMOD
static __inline fixint_t __modXi3(fixint_t a, fixint_t b) {
const int N = (int)(sizeof(fixint_t) * CHAR_BIT) - 1;
fixint_t s = b >> N; // s = b < 0 ? -1 : 0
fixuint_t b_u = (fixuint_t)(b ^ s) + (-s); // negate if s == -1
s = a >> N; // s = a < 0 ? -1 : 0
fixuint_t a_u = (fixuint_t)(a ^ s) + (-s); // negate if s == -1
fixuint_t res;
ASSIGN_UMOD(res, a_u, b_u);
return (res ^ s) + (-s); // negate if s == -1
}
#endif // ASSIGN_UMOD
@@ -0,0 +1,114 @@
//===-- int_endianness.h - configuration header for compiler-rt -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a configuration header for 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
// ..
#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__)
#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
// ..
// 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
@@ -0,0 +1,171 @@
//===-- int_lib.h - configuration header for compiler-rt -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a configuration header for 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).
// ABI macro definitions
#if __ARM_EABI__
#ifdef COMPILER_RT_ARMHF_TARGET
#define COMPILER_RT_ABI
#else
#define COMPILER_RT_ABI __attribute__((__pcs__("aapcs")))
#endif
#else
#define COMPILER_RT_ABI
#endif
#define AEABI_RTABI __attribute__((__pcs__("aapcs")))
#if defined(_MSC_VER) && !defined(__clang__)
#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
#define STR(a) #a
#define XSTR(a) STR(a)
#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name
#if defined(__ELF__) || defined(__MINGW32__) || defined(__wasm__) || \
defined(_AIX)
#define COMPILER_RT_ALIAS(name, aliasname) \
COMPILER_RT_ABI __typeof(name) aliasname __attribute__((__alias__(#name)));
#elif defined(__APPLE__)
#if defined(VISIBILITY_HIDDEN)
#define COMPILER_RT_ALIAS_VISIBILITY(name) \
__asm__(".private_extern " SYMBOL_NAME(name));
#else
#define COMPILER_RT_ALIAS_VISIBILITY(name)
#endif
#define COMPILER_RT_ALIAS(name, aliasname) \
__asm__(".globl " SYMBOL_NAME(aliasname)); \
COMPILER_RT_ALIAS_VISIBILITY(aliasname) \
__asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \
COMPILER_RT_ABI __typeof(name) aliasname;
#elif defined(_WIN32)
#define COMPILER_RT_ALIAS(name, aliasname)
#else
#error Unsupported target
#endif
#if (defined(__FreeBSD__) || defined(__NetBSD__)) && \
(defined(_KERNEL) || defined(_STANDALONE))
//
// Kernel and boot environment can't use normal headers,
// so use the equivalent system headers.
// NB: FreeBSD (and OpenBSD) deprecate machine/limits.h in
// favour of sys/limits.h, so prefer the former, but fall
// back on the latter if not available since NetBSD only has
// the latter.
//
#if defined(__has_include) && __has_include(<sys/limits.h>)
#include <sys/limits.h>
#else
#include <machine/limits.h>
#endif
#include <sys/stdint.h>
#include <sys/types.h>
#else
// Include the standard compiler builtin headers we use functionality from.
#include <float.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.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 int __paritysi2(si_int a);
COMPILER_RT_ABI 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 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>
int __inline __builtin_ctz(uint32_t value) {
unsigned long trailing_zero = 0;
if (_BitScanForward(&trailing_zero, value))
return trailing_zero;
return 32;
}
int __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)
int __inline __builtin_clzll(uint64_t value) {
unsigned long leading_zero = 0;
if (_BitScanReverse64(&leading_zero, value))
return 63 - leading_zero;
return 64;
}
#else
int __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
bool __inline __builtin_sadd_overflow(int x, int y, int *result) {
if ((x < 0) != (y < 0)) {
*result = x + y;
return false;
}
int tmp = (unsigned int)x + (unsigned int)y;
if ((tmp < 0) != (x < 0))
return true;
*result = tmp;
return false;
}
#endif // defined(_MSC_VER) && !defined(__clang__)
#endif // INT_LIB_H
@@ -0,0 +1,98 @@
//===-- int_math.h - internal math inlines --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is 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>
#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_fmaxl(x, y) __max((x), (y))
#else
#define crt_fmaxl(x, y) __builtin_fmaxl((x), (y))
#endif
#if defined(_MSC_VER) && !defined(__clang__)
#define crt_logbl(x) logbl((x))
#else
#define crt_logbl(x) __builtin_logbl((x))
#endif
#if defined(_MSC_VER) && !defined(__clang__)
#define crt_scalbnl(x, y) scalbnl((x), (y))
#else
#define crt_scalbnl(x, y) __builtin_scalbnl((x), (y))
#endif
#endif // INT_MATH_H
@@ -0,0 +1,198 @@
//===-- int_lib.h - configuration header for compiler-rt -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is 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 int32_t si_int;
typedef uint32_t su_int;
#if UINT_MAX == 0xFFFFFFFF
#define clzsi __builtin_clz
#define ctzsi __builtin_ctz
#elif ULONG_MAX == 0xFFFFFFFF
#define clzsi __builtin_clzl
#define ctzsi __builtin_ctzl
#else
#error could not determine appropriate clzsi macro for this system
#endif
typedef int64_t di_int;
typedef uint64_t 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;
#if defined(__LP64__) || defined(__wasm__) || defined(__mips64) || \
defined(__riscv) || defined(_WIN64)
#define CRT_HAS_128BIT
#endif
// MSVC doesn't have a working 128bit integer type. Users should really compile
// compiler-rt with clang, but if they happen to be doing a standalone build for
// asan or something else, disable the 128 bit parts so things sort of work.
#if defined(_MSC_VER) && !defined(__clang__)
#undef 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
// FreeBSD's boot environment does not support using floating-point and poisons
// the float and double keywords.
#if defined(__FreeBSD__) && defined(_STANDALONE)
#define CRT_HAS_FLOATING_POINT 0
#else
#define CRT_HAS_FLOATING_POINT 1
#endif
#if CRT_HAS_FLOATING_POINT
typedef union {
su_int u;
float f;
} float_bits;
typedef union {
udwords u;
double f;
} double_bits;
#endif
typedef struct {
#if _YUGA_LITTLE_ENDIAN
udwords low;
udwords high;
#else
udwords high;
udwords low;
#endif // _YUGA_LITTLE_ENDIAN
} uqwords;
// Check if the target supports 80 bit extended precision long doubles.
// Notably, on x86 Windows, MSVC only provides a 64-bit long double, but GCC
// still makes it 80 bits. Clang will match whatever compiler it is trying to
// be compatible with. On 32-bit x86 Android, long double is 64 bits, while on
// x86_64 Android, long double is 128 bits.
#if (defined(__i386__) || defined(__x86_64__)) && \
!(defined(_MSC_VER) || defined(__ANDROID__))
#define HAS_80_BIT_LONG_DOUBLE 1
#elif defined(__m68k__) || defined(__ia64__)
#define HAS_80_BIT_LONG_DOUBLE 1
#else
#define HAS_80_BIT_LONG_DOUBLE 0
#endif
#if CRT_HAS_FLOATING_POINT
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
#endif // INT_TYPES_H
@@ -0,0 +1,47 @@
//===-- int_util.h - internal utility functions ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is 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
// Force unrolling the code specified to be repeated N times.
#define REPEAT_0_TIMES(code_to_repeat) /* do nothing */
#define REPEAT_1_TIMES(code_to_repeat) code_to_repeat
#define REPEAT_2_TIMES(code_to_repeat) \
REPEAT_1_TIMES(code_to_repeat) \
code_to_repeat
#define REPEAT_3_TIMES(code_to_repeat) \
REPEAT_2_TIMES(code_to_repeat) \
code_to_repeat
#define REPEAT_4_TIMES(code_to_repeat) \
REPEAT_3_TIMES(code_to_repeat) \
code_to_repeat
#define REPEAT_N_TIMES_(N, code_to_repeat) REPEAT_##N##_TIMES(code_to_repeat)
#define REPEAT_N_TIMES(N, code_to_repeat) REPEAT_N_TIMES_(N, code_to_repeat)
#endif // INT_UTIL_H
@@ -0,0 +1,38 @@
//===-- lshrdi3.c - Implement __lshrdi3 -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements __lshrdi3 for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
// Returns: logical a >> b
// Precondition: 0 <= b < bits_in_dword
COMPILER_RT_ABI di_int __lshrdi3(di_int a, int b) {
const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
udwords input;
udwords result;
input.all = a;
if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ {
result.s.high = 0;
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__)
COMPILER_RT_ALIAS(__lshrdi3, __aeabi_llsr)
#endif
@@ -0,0 +1,32 @@
//===-- popcountdi2.c - Implement __popcountdi2 ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements __popcountdi2 for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
// Returns: count of 1 bits
COMPILER_RT_ABI int __popcountdi2(di_int a) {
du_int x2 = (du_int)a;
x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL);
// Every 2 bits holds the sum of every pair of bits (32)
x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL);
// Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16)
x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL;
// Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8)
su_int x = (su_int)(x2 + (x2 >> 32));
// The lower 32 bits hold four 16 bit sums (5 significant bits).
// Upper 32 bits are garbage
x = x + (x >> 16);
// The lower 16 bits hold two 32 bit sums (6 significant bits).
// Upper 16 bits are garbage
return (x + (x >> 8)) & 0x0000007F; // (7 significant bits)
}
@@ -0,0 +1,29 @@
//===-- popcountsi2.c - Implement __popcountsi2 ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements __popcountsi2 for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
// Returns: count of 1 bits
COMPILER_RT_ABI int __popcountsi2(si_int a) {
su_int x = (su_int)a;
x = x - ((x >> 1) & 0x55555555);
// Every 2 bits holds the sum of every pair of bits
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
// Every 4 bits holds the sum of every 4-set of bits (3 significant bits)
x = (x + (x >> 4)) & 0x0F0F0F0F;
// Every 8 bits holds the sum of every 8-set of bits (4 significant bits)
x = (x + (x >> 16));
// The lower 16 bits hold two 8 bit sums (5 significant bits).
// Upper 16 bits are garbage
return (x + (x >> 8)) & 0x0000003F; // (6 significant bits)
}
@@ -0,0 +1,200 @@
//===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements __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
#if defined(_MSC_VER) && !defined(__clang__)
// MSVC throws a warning about mod 0 here, disable it for builds that
// warn-as-error
#pragma warning(push)
#pragma warning(disable : 4723 4724)
#endif
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 >> ctzsi(d.s.high);
}
// K K
// ---
// K 0
sr = clzsi(d.s.high) - clzsi(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 = ctzsi(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 + clzsi(d.s.low) - clzsi(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 = clzsi(d.s.high) - clzsi(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;
}
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(pop)
#endif
@@ -0,0 +1,44 @@
#
# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of ARM nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
COMPILER_RT_SRCS := lib/compiler-rt/builtins/popcountdi2.c \
lib/compiler-rt/builtins/popcountsi2.c
ifeq (${ARCH},aarch32)
COMPILER_RT_SRCS += lib/compiler-rt/builtins/arm/aeabi_ldivmod.S \
lib/compiler-rt/builtins/arm/aeabi_uldivmod.S \
lib/compiler-rt/builtins/arm/aeabi_memcpy.S \
lib/compiler-rt/builtins/arm/aeabi_memset.S \
lib/compiler-rt/builtins/ctzdi2.c \
lib/compiler-rt/builtins/divdi3.c \
lib/compiler-rt/builtins/divmoddi4.c \
lib/compiler-rt/builtins/lshrdi3.c \
lib/compiler-rt/builtins/udivmoddi4.c
endif