Software APIs
math_builtins.c
Go to the documentation of this file.
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 /**
6  * @file
7  * @brief Implementations of libgcc-style polyfills for arithmetic.
8  *
9  * This file has no header, since its functions should not be called directly;
10  * the compiler will generate calls into them as needed.
11  *
12  * The functions have names like `_ot_builtin_*`, rather than their libgcc
13  * names, so that they can coexist with libgcc/libcompiler-rt on the host-side
14  * for the purpose of unit tests. The linker aliases for the libgcc names only
15  * exist on the device-side.
16  *
17  * See https://github.com/llvm/llvm-project/tree/main/compiler-rt/lib/builtins
18  * for a detailed specification of the ABI we implement in this file.
19  *
20  * The provided functions here are:
21  * - 64-bit shifts.
22  * - 32-bit popcount, parity, bswap, clz, ctz, and find first.
23  *
24  * Although the RISC-V B extension provides instructions for some ofthese, we
25  * currently do not require using a Clang that is aware of how to codegen them,
26  * so LLVM may choose to emit libgcc polyfill symbols (like the following)
27  * instead. Once we mandate such a Clang, they should be removed.
28  */
29 
30 #include <stdint.h>
31 #include <stdnoreturn.h>
32 
34 
35 // Linker aliases for libgcc symbols.
36 #ifdef OT_PLATFORM_RV32
37 
38 extern noreturn void
39 _ot_builtin_div64_intentionally_not_implemented_see_pull_11451(void);
40 
41 // "Trap" polyfills to catch uses of u64 divsion and display an "error" via
42 // the name of an undefined symbol.
43 //
44 // Of course, this depends on people linking this file in... but hopefully it
45 // is sufficiently pervasive that won't be an issue; at any rate, it means
46 // people will land somewhere when they grep for __udivdi3 and friends.
47 OT_WEAK int64_t __divdi3(int64_t a, int64_t b) {
48  _ot_builtin_div64_intentionally_not_implemented_see_pull_11451();
49 }
50 OT_WEAK uint64_t __udivdi3(uint64_t a, uint64_t b) {
51  _ot_builtin_div64_intentionally_not_implemented_see_pull_11451();
52 }
53 OT_WEAK int64_t __moddi3(int64_t a, int64_t b) {
54  _ot_builtin_div64_intentionally_not_implemented_see_pull_11451();
55 }
56 OT_WEAK uint64_t __umoddi3(uint64_t a, uint64_t b) {
57  _ot_builtin_div64_intentionally_not_implemented_see_pull_11451();
58 }
59 OT_WEAK int64_t __divmoddi4(int64_t a, int64_t b, int64_t *rem) {
60  _ot_builtin_div64_intentionally_not_implemented_see_pull_11451();
61 }
62 OT_WEAK uint64_t __udivmoddi4(uint64_t a, uint64_t b, uint64_t *rem) {
63  _ot_builtin_div64_intentionally_not_implemented_see_pull_11451();
64 }
65 #endif // OT_PLATFORM_RV32