1*4d6fc14bSjoerg /*===-- int128_builtins.cpp - Implement __muloti4 --------------------------=== 2*4d6fc14bSjoerg * 3*4d6fc14bSjoerg * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*4d6fc14bSjoerg * See https://llvm.org/LICENSE.txt for license information. 5*4d6fc14bSjoerg * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*4d6fc14bSjoerg * 7*4d6fc14bSjoerg * ===----------------------------------------------------------------------=== 8*4d6fc14bSjoerg * 9*4d6fc14bSjoerg * This file implements __muloti4, and is stolen from the compiler_rt library. 10*4d6fc14bSjoerg * 11*4d6fc14bSjoerg * FIXME: we steal and re-compile it into filesystem, which uses __int128_t, 12*4d6fc14bSjoerg * and requires this builtin when sanitized. See llvm.org/PR30643 13*4d6fc14bSjoerg * 14*4d6fc14bSjoerg * ===----------------------------------------------------------------------=== 15*4d6fc14bSjoerg */ 16*4d6fc14bSjoerg #include "__config" 17*4d6fc14bSjoerg #include "climits" 18*4d6fc14bSjoerg 19*4d6fc14bSjoerg #if !defined(_LIBCPP_HAS_NO_INT128) 20*4d6fc14bSjoerg 21*4d6fc14bSjoerg extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_FUNC_VIS __muloti4(__int128_t a,__int128_t b,int * overflow)22*4d6fc14bSjoerg__int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) { 23*4d6fc14bSjoerg const int N = (int)(sizeof(__int128_t) * CHAR_BIT); 24*4d6fc14bSjoerg const __int128_t MIN = (__int128_t)1 << (N - 1); 25*4d6fc14bSjoerg const __int128_t MAX = ~MIN; 26*4d6fc14bSjoerg *overflow = 0; 27*4d6fc14bSjoerg __int128_t result = a * b; 28*4d6fc14bSjoerg if (a == MIN) { 29*4d6fc14bSjoerg if (b != 0 && b != 1) 30*4d6fc14bSjoerg *overflow = 1; 31*4d6fc14bSjoerg return result; 32*4d6fc14bSjoerg } 33*4d6fc14bSjoerg if (b == MIN) { 34*4d6fc14bSjoerg if (a != 0 && a != 1) 35*4d6fc14bSjoerg *overflow = 1; 36*4d6fc14bSjoerg return result; 37*4d6fc14bSjoerg } 38*4d6fc14bSjoerg __int128_t sa = a >> (N - 1); 39*4d6fc14bSjoerg __int128_t abs_a = (a ^ sa) - sa; 40*4d6fc14bSjoerg __int128_t sb = b >> (N - 1); 41*4d6fc14bSjoerg __int128_t abs_b = (b ^ sb) - sb; 42*4d6fc14bSjoerg if (abs_a < 2 || abs_b < 2) 43*4d6fc14bSjoerg return result; 44*4d6fc14bSjoerg if (sa == sb) { 45*4d6fc14bSjoerg if (abs_a > MAX / abs_b) 46*4d6fc14bSjoerg *overflow = 1; 47*4d6fc14bSjoerg } else { 48*4d6fc14bSjoerg if (abs_a > MIN / -abs_b) 49*4d6fc14bSjoerg *overflow = 1; 50*4d6fc14bSjoerg } 51*4d6fc14bSjoerg return result; 52*4d6fc14bSjoerg } 53*4d6fc14bSjoerg 54*4d6fc14bSjoerg #endif 55