[NFC][Py Reformat] Added more commits to .git-blame-ignore-revs
[llvm-project.git] / libc / src / __support / integer_utils.h
blobaedcd353436f991542e0ca89cd03bbc7ad3a9526
1 //===-- Utilities for integers. ---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC_SUPPORT_INTEGER_UTILS_H
10 #define LLVM_LIBC_SRC_SUPPORT_INTEGER_UTILS_H
12 #include "src/__support/CPP/type_traits.h"
13 #include "src/__support/common.h"
15 #include "builtin_wrappers.h"
16 #include "number_pair.h"
18 #include <stdint.h>
20 namespace __llvm_libc {
22 template <typename T> NumberPair<T> full_mul(T a, T b);
24 template <>
25 LIBC_INLINE NumberPair<uint32_t> full_mul<uint32_t>(uint32_t a, uint32_t b) {
26 uint64_t prod = uint64_t(a) * uint64_t(b);
27 NumberPair<uint32_t> result;
28 result.lo = uint32_t(prod);
29 result.hi = uint32_t(prod >> 32);
30 return result;
33 template <>
34 LIBC_INLINE NumberPair<uint64_t> full_mul<uint64_t>(uint64_t a, uint64_t b) {
35 #ifdef __SIZEOF_INT128__
36 __uint128_t prod = __uint128_t(a) * __uint128_t(b);
37 NumberPair<uint64_t> result;
38 result.lo = uint64_t(prod);
39 result.hi = uint64_t(prod >> 64);
40 return result;
41 #else
42 NumberPair<uint64_t> pa = split(a);
43 NumberPair<uint64_t> pb = split(b);
44 NumberPair<uint64_t> prod;
46 prod.lo = pa.lo * pb.lo; // exact
47 prod.hi = pa.hi * pb.hi; // exact
48 NumberPair<uint64_t> lo_hi = split(pa.lo * pb.hi); // exact
49 NumberPair<uint64_t> hi_lo = split(pa.hi * pb.lo); // exact
51 auto r1 = add_with_carry(prod.lo, lo_hi.lo << 32, uint64_t(0));
52 prod.lo = r1.sum;
53 prod.hi = add_with_carry(prod.hi, lo_hi.hi, r1.carry).sum;
55 auto r2 = add_with_carry(prod.lo, hi_lo.lo << 32, uint64_t(0));
56 prod.lo = r2.sum;
57 prod.hi = add_with_carry(prod.hi, hi_lo.hi, r2.carry).sum;
59 return prod;
60 #endif // __SIZEOF_INT128__
63 } // namespace __llvm_libc
65 #endif // LLVM_LIBC_SRC_SUPPORT_INTEGER_UTILS_H