84 lines
1.7 KiB
D
84 lines
1.7 KiB
D
module core.checkedint;
|
|
|
|
version(LDC)
|
|
{
|
|
import ldc.intrinsics;
|
|
}
|
|
|
|
pragma(inline, true)
|
|
uint addu()(uint x, uint y, ref bool overflow)
|
|
{
|
|
version (LDC)
|
|
{
|
|
if (!__ctfe)
|
|
{
|
|
auto res = llvm_uadd_with_overflow(x, y);
|
|
overflow |= res.overflow;
|
|
return res.result;
|
|
}
|
|
}
|
|
immutable uint r = x + y;
|
|
immutable bool o = r < x;
|
|
assert(o == (r < y));
|
|
if (o)
|
|
overflow = true;
|
|
return r;
|
|
}
|
|
|
|
uint mulu()(uint x, uint y, ref bool overflow)
|
|
{
|
|
version (D_InlineAsm_X86) enum useAsm = true;
|
|
else version (D_InlineAsm_X86_64) enum useAsm = true;
|
|
else enum useAsm = false;
|
|
|
|
version (LDC)
|
|
{
|
|
if (!__ctfe)
|
|
{
|
|
auto res = llvm_umul_with_overflow(x, y);
|
|
overflow |= res.overflow;
|
|
return res.result;
|
|
}
|
|
}
|
|
else static if (useAsm)
|
|
{
|
|
if (!__ctfe)
|
|
{
|
|
uint r;
|
|
bool o;
|
|
asm pure nothrow @nogc @trusted
|
|
{
|
|
mov EAX, x;
|
|
mul y; // EDX:EAX = EAX * y
|
|
mov r, EAX;
|
|
setc o;
|
|
}
|
|
overflow |= o;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
immutable ulong r = ulong(x) * ulong(y);
|
|
if (r >> 32)
|
|
overflow = true;
|
|
return cast(uint) r;
|
|
}
|
|
|
|
pragma(inline, true)
|
|
int adds()(int x, int y, ref bool overflow)
|
|
{
|
|
version (LDC)
|
|
{
|
|
if (!__ctfe)
|
|
{
|
|
auto res = llvm_sadd_with_overflow(x, y);
|
|
overflow |= res.overflow;
|
|
return res.result;
|
|
}
|
|
}
|
|
long r = cast(long)x + cast(long)y;
|
|
if (r < int.min || r > int.max)
|
|
overflow = true;
|
|
return cast(int)r;
|
|
}
|