1*58b9f456SAndroid Build Coastguard Worker /*===-- int128_builtins.cpp - Implement __muloti4 --------------------------=== 2*58b9f456SAndroid Build Coastguard Worker * 3*58b9f456SAndroid Build Coastguard Worker * The LLVM Compiler Infrastructure 4*58b9f456SAndroid Build Coastguard Worker * 5*58b9f456SAndroid Build Coastguard Worker * This file is dual licensed under the MIT and the University of Illinois Open 6*58b9f456SAndroid Build Coastguard Worker * Source Licenses. See LICENSE.TXT for details. 7*58b9f456SAndroid Build Coastguard Worker * 8*58b9f456SAndroid Build Coastguard Worker * ===----------------------------------------------------------------------=== 9*58b9f456SAndroid Build Coastguard Worker * 10*58b9f456SAndroid Build Coastguard Worker * This file implements __muloti4, and is stolen from the compiler_rt library. 11*58b9f456SAndroid Build Coastguard Worker * 12*58b9f456SAndroid Build Coastguard Worker * FIXME: we steal and re-compile it into filesystem, which uses __int128_t, 13*58b9f456SAndroid Build Coastguard Worker * and requires this builtin when sanitized. See llvm.org/PR30643 14*58b9f456SAndroid Build Coastguard Worker * 15*58b9f456SAndroid Build Coastguard Worker * ===----------------------------------------------------------------------=== 16*58b9f456SAndroid Build Coastguard Worker */ 17*58b9f456SAndroid Build Coastguard Worker #include "__config" 18*58b9f456SAndroid Build Coastguard Worker #include "climits" 19*58b9f456SAndroid Build Coastguard Worker 20*58b9f456SAndroid Build Coastguard Worker #if !defined(_LIBCPP_HAS_NO_INT128) 21*58b9f456SAndroid Build Coastguard Worker 22*58b9f456SAndroid Build Coastguard Worker extern "C" __attribute__((no_sanitize("undefined"))) __muloti4(__int128_t a,__int128_t b,int * overflow)23*58b9f456SAndroid Build Coastguard Worker__int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) { 24*58b9f456SAndroid Build Coastguard Worker const int N = (int)(sizeof(__int128_t) * CHAR_BIT); 25*58b9f456SAndroid Build Coastguard Worker const __int128_t MIN = (__int128_t)1 << (N - 1); 26*58b9f456SAndroid Build Coastguard Worker const __int128_t MAX = ~MIN; 27*58b9f456SAndroid Build Coastguard Worker *overflow = 0; 28*58b9f456SAndroid Build Coastguard Worker __int128_t result = a * b; 29*58b9f456SAndroid Build Coastguard Worker if (a == MIN) { 30*58b9f456SAndroid Build Coastguard Worker if (b != 0 && b != 1) 31*58b9f456SAndroid Build Coastguard Worker *overflow = 1; 32*58b9f456SAndroid Build Coastguard Worker return result; 33*58b9f456SAndroid Build Coastguard Worker } 34*58b9f456SAndroid Build Coastguard Worker if (b == MIN) { 35*58b9f456SAndroid Build Coastguard Worker if (a != 0 && a != 1) 36*58b9f456SAndroid Build Coastguard Worker *overflow = 1; 37*58b9f456SAndroid Build Coastguard Worker return result; 38*58b9f456SAndroid Build Coastguard Worker } 39*58b9f456SAndroid Build Coastguard Worker __int128_t sa = a >> (N - 1); 40*58b9f456SAndroid Build Coastguard Worker __int128_t abs_a = (a ^ sa) - sa; 41*58b9f456SAndroid Build Coastguard Worker __int128_t sb = b >> (N - 1); 42*58b9f456SAndroid Build Coastguard Worker __int128_t abs_b = (b ^ sb) - sb; 43*58b9f456SAndroid Build Coastguard Worker if (abs_a < 2 || abs_b < 2) 44*58b9f456SAndroid Build Coastguard Worker return result; 45*58b9f456SAndroid Build Coastguard Worker if (sa == sb) { 46*58b9f456SAndroid Build Coastguard Worker if (abs_a > MAX / abs_b) 47*58b9f456SAndroid Build Coastguard Worker *overflow = 1; 48*58b9f456SAndroid Build Coastguard Worker } else { 49*58b9f456SAndroid Build Coastguard Worker if (abs_a > MIN / -abs_b) 50*58b9f456SAndroid Build Coastguard Worker *overflow = 1; 51*58b9f456SAndroid Build Coastguard Worker } 52*58b9f456SAndroid Build Coastguard Worker return result; 53*58b9f456SAndroid Build Coastguard Worker } 54*58b9f456SAndroid Build Coastguard Worker 55*58b9f456SAndroid Build Coastguard Worker #endif 56