Daniel Dunbar f287008791 Use a private compilerrt_abort() define instead of calling abort directly.
- Fiddling with abort directly is annoying given the way we use system includes, although it would be nice to fix this so we could make sure calling abort directly is verboten.

llvm-svn: 100014
2010-03-31 17:00:45 +00:00

62 lines
1.4 KiB
C

/* ===-- mulvti3.c - Implement __mulvti3 -----------------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
*
* This file implements __mulvti3 for the compiler_rt library.
*
* ===----------------------------------------------------------------------===
*/
#if __x86_64
#include "int_lib.h"
#include <stdlib.h>
/* Returns: a * b */
/* Effects: aborts if a * b overflows */
ti_int
__mulvti3(ti_int a, ti_int b)
{
const int N = (int)(sizeof(ti_int) * CHAR_BIT);
const ti_int MIN = (ti_int)1 << (N-1);
const ti_int MAX = ~MIN;
if (a == MIN)
{
if (b == 0 || b == 1)
return a * b;
compilerrt_abort();
}
if (b == MIN)
{
if (a == 0 || a == 1)
return a * b;
compilerrt_abort();
}
ti_int sa = a >> (N - 1);
ti_int abs_a = (a ^ sa) - sa;
ti_int sb = b >> (N - 1);
ti_int abs_b = (b ^ sb) - sb;
if (abs_a < 2 || abs_b < 2)
return a * b;
if (sa == sb)
{
if (abs_a > MAX / abs_b)
compilerrt_abort();
}
else
{
if (abs_a > MIN / -abs_b)
compilerrt_abort();
}
return a * b;
}
#endif