1 //===-- Utilities for integers. ---------------------------------*- C++ -*-===//
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
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"
20 namespace __llvm_libc
{
22 template <typename T
> NumberPair
<T
> full_mul(T a
, T b
);
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);
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);
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));
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));
57 prod
.hi
= add_with_carry(prod
.hi
, hi_lo
.hi
, r2
.carry
).sum
;
60 #endif // __SIZEOF_INT128__
63 } // namespace __llvm_libc
65 #endif // LLVM_LIBC_SRC_SUPPORT_INTEGER_UTILS_H