]> granicus.if.org Git - clang/commitdiff
Intrin: Add _umul128
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 2 Dec 2014 23:30:24 +0000 (23:30 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 2 Dec 2014 23:30:24 +0000 (23:30 +0000)
Implement _umul128; it provides the high and low halves of a 128-bit
multiply.  We can simply use our __int128 arithmetic to implement this,
we generate great code for it:
        movq    %rdx, %rax
        mulq    %rcx
        movq    %rdx, (%r8)
        retq

Differential Revision: http://reviews.llvm.org/D6486

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@223175 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/Intrin.h

index 016c480adf2664fd93d8b3a96f4903923a2346be..89e0d0c82d8e0c686d9235fdd48cefa8d6ab85e5 100644 (file)
@@ -417,9 +417,18 @@ int __cdecl _setjmpex(jmp_buf);
 #endif
 unsigned __int64 _shlx_u64(unsigned __int64, unsigned int);
 unsigned __int64 shrx_u64(unsigned __int64, unsigned int);
-unsigned __int64 _umul128(unsigned __int64 _Multiplier,
-                          unsigned __int64 _Multiplicand,
-                          unsigned __int64 *_HighProduct);
+/*
+ * Multiply two 64-bit integers and obtain a 64-bit result.
+ * The low-half is returned directly and the high half is in an out parameter.
+ */
+static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+_umul128(unsigned __int64 _Multiplier, unsigned __int64 _Multiplicand,
+         unsigned __int64 *_HighProduct) {
+  unsigned __int128 _FullProduct =
+      (unsigned __int128)_Multiplier * (unsigned __int128)_Multiplicand;
+  *_HighProduct = FullProduct >> 64;
+  return FullProduct;
+}
 void __cdecl _xrstor64(void const *, unsigned __int64);
 void __cdecl _xsave64(void *, unsigned __int64);
 void __cdecl _xsaveopt64(void *, unsigned __int64);