mulvsi3.c revision 276789
1133362Sobrien/* ===-- mulvsi3.c - Implement __mulvsi3 -----------------------------------=== 2234449Sobrien * 3133362Sobrien * The LLVM Compiler Infrastructure 4298107Sgjb * 5133365Sobrien * This file is dual licensed under the MIT and the University of Illinois Open 6267897Sdelphij * Source Licenses. See LICENSE.TXT for details. 7267897Sdelphij * 8133362Sobrien * ===----------------------------------------------------------------------=== 9133362Sobrien * 10195767Skensmith * This file implements __mulvsi3 for the compiler_rt library. 11275024Sbapt * 12133362Sobrien * ===----------------------------------------------------------------------=== 13133362Sobrien */ 14191771Sobrien 15298192Sdelphij#include "int_lib.h" 16191771Sobrien 17137887Sobrien/* Returns: a * b */ 18133362Sobrien 19133370Sobrien/* Effects: aborts if a * b overflows */ 20133362Sobrien 21159769SobrienCOMPILER_RT_ABI si_int 22302222Sdelphij__mulvsi3(si_int a, si_int b) 23133362Sobrien{ 24208342Smarius const int N = (int)(sizeof(si_int) * CHAR_BIT); 25201381Sed const si_int MIN = (si_int)1 << (N-1); 26186693Sobrien const si_int MAX = ~MIN; 27133362Sobrien if (a == MIN) 28186693Sobrien { 29133362Sobrien if (b == 0 || b == 1) 30133362Sobrien return a * b; 31267897Sdelphij compilerrt_abort(); 32267897Sdelphij } 33267897Sdelphij if (b == MIN) 34133362Sobrien { 35133362Sobrien if (a == 0 || a == 1) 36265464Sdelphij return a * b; 37133362Sobrien compilerrt_abort(); 38133362Sobrien } 39299289Sbdrewery si_int sa = a >> (N - 1); 40133362Sobrien si_int abs_a = (a ^ sa) - sa; 41133362Sobrien si_int sb = b >> (N - 1); 42133362Sobrien si_int abs_b = (b ^ sb) - sb; 43302222Sdelphij if (abs_a < 2 || abs_b < 2) 44302222Sdelphij return a * b; 45240377Sobrien if (sa == sb) 46133362Sobrien { 47136681Sru if (abs_a > MAX / abs_b) 48136681Sru compilerrt_abort(); 49133362Sobrien } 50133362Sobrien else 51133362Sobrien { 52133362Sobrien if (abs_a > MIN / -abs_b) 53133362Sobrien compilerrt_abort(); 54133362Sobrien } 55133362Sobrien return a * b; 56133362Sobrien} 57302221Sdelphij