1 /*************************************************************************************************** 2 * 3 * Supplementary integer math functions. 4 * 5 * Authors: 6 * $(LINK2 mailto:Marco.Leise@gmx.de, Marco Leise) 7 * 8 * Copyright: 9 * © 2017 $(LINK2 mailto:Marco.Leise@gmx.de, Marco Leise) 10 * 11 * License: 12 * $(LINK2 http://www.gnu.org/licenses/gpl-3.0, GNU General Public License 3.0) 13 * 14 **************************************************************************************************/ 15 module fast.intmath; 16 17 import fast.internal.helpers; 18 import fast.internal.sysdef; 19 20 21 version (LDC) 22 { 23 @safe @nogc pure nothrow 24 ulong mulu(ulong x, ulong y, ref bool overflow) 25 { 26 import ldc.intrinsics; 27 auto res = llvm_umul_with_overflow(x, y); 28 overflow = res.overflow; 29 return res.result; 30 } 31 } 32 else static if (isPosix && isGDC && (isAMD64 || isX86)) 33 { 34 @nogc pure nothrow 35 ulong mulu(ulong x, ulong y, ref bool overflow) 36 { 37 version (GNU) 38 { 39 ulong lo; 40 version (X86) asm { " 41 cmp $0, 4+%2 42 je 1f 43 cmp $0, 4%3 44 je 1f 45 movb $1, %1 46 1: 47 mov 4+%2, %%eax 48 mull %3 49 jno 2f 50 movb $1, %1 51 2: 52 mov %%eax, %%ecx 53 mov %2, %%eax 54 mull 4%3 55 jno 3f 56 movb $1, %1 57 3: 58 add %%eax, %%ecx 59 jno 4f 60 movb $1, %1 61 4: 62 mov %2, %%eax 63 mull %3 64 add %%ecx, %%edx 65 jnc 5f 66 movb $1, %1 67 5: 68 " : "=&A" lo, "+*m" overflow : "m" x, "m" y : "ecx"; } 69 else asm { "mul %3\njno 1f\nmovb $1, %1\n1:\n" : "=a" lo, "+*m" overflow : "a" x, "r" y : "rdx"; } 70 return lo; 71 } 72 } 73 } 74 else 75 { 76 // DMD is already faster than my ASM code above, no need to improve. Good job Walter et al. 77 import core.checkedint; 78 alias mulu = core.checkedint.mulu; 79 }