[Hexagon] Use llvm::children (NFC)
[llvm-project.git] / flang / lib / Evaluate / int-power.h
blob0d6a133ae73c51c1374baa1ae36c33f262dbc906
1 //===-- lib/Evaluate/int-power.h --------------------------------*- 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 FORTRAN_EVALUATE_INT_POWER_H_
10 #define FORTRAN_EVALUATE_INT_POWER_H_
12 // Computes an integer power of a real or complex value.
14 #include "flang/Evaluate/target.h"
16 namespace Fortran::evaluate {
18 template <typename REAL, typename INT>
19 ValueWithRealFlags<REAL> TimesIntPowerOf(const REAL &factor, const REAL &base,
20 const INT &power,
21 Rounding rounding = TargetCharacteristics::defaultRounding) {
22 ValueWithRealFlags<REAL> result{factor};
23 if (base.IsNotANumber()) {
24 result.value = REAL::NotANumber();
25 result.flags.set(RealFlag::InvalidArgument);
26 } else if (power.IsZero()) {
27 if (base.IsZero() || base.IsInfinite()) {
28 result.flags.set(RealFlag::InvalidArgument);
30 } else {
31 bool negativePower{power.IsNegative()};
32 INT absPower{power.ABS().value};
33 REAL squares{base};
34 int nbits{INT::bits - absPower.LEADZ()};
35 for (int j{0}; j < nbits; ++j) {
36 if (absPower.BTEST(j)) {
37 if (negativePower) {
38 result.value = result.value.Divide(squares, rounding)
39 .AccumulateFlags(result.flags);
40 } else {
41 result.value = result.value.Multiply(squares, rounding)
42 .AccumulateFlags(result.flags);
45 squares =
46 squares.Multiply(squares, rounding).AccumulateFlags(result.flags);
49 return result;
52 template <typename REAL, typename INT>
53 ValueWithRealFlags<REAL> IntPower(const REAL &base, const INT &power,
54 Rounding rounding = TargetCharacteristics::defaultRounding) {
55 REAL one{REAL::FromInteger(INT{1}).value};
56 return TimesIntPowerOf(one, base, power, rounding);
58 } // namespace Fortran::evaluate
59 #endif // FORTRAN_EVALUATE_INT_POWER_H_