Skip to content

Commit fdbcb93

Browse files
committed
[flang][runtime] Added offload markup for FortranDecimal APIs.
1 parent 84b755c commit fdbcb93

File tree

3 files changed

+52
-41
lines changed

3 files changed

+52
-41
lines changed

flang/lib/Decimal/big-radix-floating-point.h

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -68,30 +68,30 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
6868
static constexpr int maxDigits{3 - minLog2AnyBit / log10Radix};
6969

7070
public:
71-
explicit BigRadixFloatingPointNumber(
71+
explicit RT_API_ATTRS BigRadixFloatingPointNumber(
7272
enum FortranRounding rounding = RoundNearest)
7373
: rounding_{rounding} {}
7474

7575
// Converts a binary floating point value.
76-
explicit BigRadixFloatingPointNumber(
76+
explicit RT_API_ATTRS BigRadixFloatingPointNumber(
7777
Real, enum FortranRounding = RoundNearest);
7878

79-
BigRadixFloatingPointNumber &SetToZero() {
79+
RT_API_ATTRS BigRadixFloatingPointNumber &SetToZero() {
8080
isNegative_ = false;
8181
digits_ = 0;
8282
exponent_ = 0;
8383
return *this;
8484
}
8585

8686
// Converts decimal floating-point to binary.
87-
ConversionToBinaryResult<PREC> ConvertToBinary();
87+
RT_API_ATTRS ConversionToBinaryResult<PREC> ConvertToBinary();
8888

8989
// Parses and converts to binary. Handles leading spaces,
9090
// "NaN", & optionally-signed "Inf". Does not skip internal
9191
// spaces.
9292
// The argument is a reference to a pointer that is left
9393
// pointing to the first character that wasn't parsed.
94-
ConversionToBinaryResult<PREC> ConvertToBinary(
94+
RT_API_ATTRS ConversionToBinaryResult<PREC> ConvertToBinary(
9595
const char *&, const char *end = nullptr);
9696

9797
// Formats a decimal floating-point number to a user buffer.
@@ -100,7 +100,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
100100
// after the last digit; the effective decimal exponent is
101101
// returned as part of the result structure so that it can be
102102
// formatted by the client.
103-
ConversionToDecimalResult ConvertToDecimal(
103+
RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal(
104104
char *, std::size_t, enum DecimalConversionFlags, int digits) const;
105105

106106
// Discard decimal digits not needed to distinguish this value
@@ -112,21 +112,22 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
112112
// This minimization necessarily assumes that the value will be
113113
// emitted and read back into the same (or less precise) format
114114
// with default rounding to the nearest value.
115-
void Minimize(
115+
RT_API_ATTRS void Minimize(
116116
BigRadixFloatingPointNumber &&less, BigRadixFloatingPointNumber &&more);
117117

118118
template <typename STREAM> STREAM &Dump(STREAM &) const;
119119

120120
private:
121-
BigRadixFloatingPointNumber(const BigRadixFloatingPointNumber &that)
121+
RT_API_ATTRS BigRadixFloatingPointNumber(
122+
const BigRadixFloatingPointNumber &that)
122123
: digits_{that.digits_}, exponent_{that.exponent_},
123124
isNegative_{that.isNegative_}, rounding_{that.rounding_} {
124125
for (int j{0}; j < digits_; ++j) {
125126
digit_[j] = that.digit_[j];
126127
}
127128
}
128129

129-
bool IsZero() const {
130+
RT_API_ATTRS bool IsZero() const {
130131
// Don't assume normalization.
131132
for (int j{0}; j < digits_; ++j) {
132133
if (digit_[j] != 0) {
@@ -140,13 +141,13 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
140141
// (When this happens during decimal-to-binary conversion,
141142
// there are more digits in the input string than can be
142143
// represented precisely.)
143-
bool IsFull() const {
144+
RT_API_ATTRS bool IsFull() const {
144145
return digits_ == digitLimit_ && digit_[digits_ - 1] >= radix / 10;
145146
}
146147

147148
// Sets *this to an unsigned integer value.
148149
// Returns any remainder.
149-
template <typename UINT> UINT SetTo(UINT n) {
150+
template <typename UINT> RT_API_ATTRS UINT SetTo(UINT n) {
150151
static_assert(
151152
std::is_same_v<UINT, common::uint128_t> || std::is_unsigned_v<UINT>);
152153
SetToZero();
@@ -173,7 +174,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
173174
}
174175
}
175176

176-
int RemoveLeastOrderZeroDigits() {
177+
RT_API_ATTRS int RemoveLeastOrderZeroDigits() {
177178
int remove{0};
178179
if (digits_ > 0 && digit_[0] == 0) {
179180
while (remove < digits_ && digit_[remove] == 0) {
@@ -197,25 +198,25 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
197198
return remove;
198199
}
199200

200-
void RemoveLeadingZeroDigits() {
201+
RT_API_ATTRS void RemoveLeadingZeroDigits() {
201202
while (digits_ > 0 && digit_[digits_ - 1] == 0) {
202203
--digits_;
203204
}
204205
}
205206

206-
void Normalize() {
207+
RT_API_ATTRS void Normalize() {
207208
RemoveLeadingZeroDigits();
208209
exponent_ += RemoveLeastOrderZeroDigits() * log10Radix;
209210
}
210211

211212
// This limited divisibility test only works for even divisors of the radix,
212213
// which is fine since it's only ever used with 2 and 5.
213-
template <int N> bool IsDivisibleBy() const {
214+
template <int N> RT_API_ATTRS bool IsDivisibleBy() const {
214215
static_assert(N > 1 && radix % N == 0, "bad modulus");
215216
return digits_ == 0 || (digit_[0] % N) == 0;
216217
}
217218

218-
template <unsigned DIVISOR> int DivideBy() {
219+
template <unsigned DIVISOR> RT_API_ATTRS int DivideBy() {
219220
Digit remainder{0};
220221
for (int j{digits_ - 1}; j >= 0; --j) {
221222
Digit q{digit_[j] / DIVISOR};
@@ -226,7 +227,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
226227
return remainder;
227228
}
228229

229-
void DivideByPowerOfTwo(int twoPow) { // twoPow <= log10Radix
230+
RT_API_ATTRS void DivideByPowerOfTwo(int twoPow) { // twoPow <= log10Radix
230231
Digit remainder{0};
231232
auto mask{(Digit{1} << twoPow) - 1};
232233
auto coeff{radix >> twoPow};
@@ -238,7 +239,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
238239
}
239240

240241
// Returns true on overflow
241-
bool DivideByPowerOfTwoInPlace(int twoPow) {
242+
RT_API_ATTRS bool DivideByPowerOfTwoInPlace(int twoPow) {
242243
if (digits_ > 0) {
243244
while (twoPow > 0) {
244245
int chunk{twoPow > log10Radix ? log10Radix : twoPow};
@@ -268,7 +269,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
268269
return false; // no overflow
269270
}
270271

271-
int AddCarry(int position = 0, int carry = 1) {
272+
RT_API_ATTRS int AddCarry(int position = 0, int carry = 1) {
272273
for (; position < digits_; ++position) {
273274
Digit v{digit_[position] + carry};
274275
if (v < radix) {
@@ -290,13 +291,13 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
290291
return carry;
291292
}
292293

293-
void Decrement() {
294+
RT_API_ATTRS void Decrement() {
294295
for (int j{0}; digit_[j]-- == 0; ++j) {
295296
digit_[j] = radix - 1;
296297
}
297298
}
298299

299-
template <int N> int MultiplyByHelper(int carry = 0) {
300+
template <int N> RT_API_ATTRS int MultiplyByHelper(int carry = 0) {
300301
for (int j{0}; j < digits_; ++j) {
301302
auto v{N * digit_[j] + carry};
302303
carry = v / radix;
@@ -305,15 +306,15 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
305306
return carry;
306307
}
307308

308-
template <int N> int MultiplyBy(int carry = 0) {
309+
template <int N> RT_API_ATTRS int MultiplyBy(int carry = 0) {
309310
if (int newCarry{MultiplyByHelper<N>(carry)}) {
310311
return AddCarry(digits_, newCarry);
311312
} else {
312313
return 0;
313314
}
314315
}
315316

316-
template <int N> int MultiplyWithoutNormalization() {
317+
template <int N> RT_API_ATTRS int MultiplyWithoutNormalization() {
317318
if (int carry{MultiplyByHelper<N>(0)}) {
318319
if (digits_ < digitLimit_) {
319320
digit_[digits_++] = carry;
@@ -326,9 +327,9 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
326327
}
327328
}
328329

329-
void LoseLeastSignificantDigit(); // with rounding
330+
RT_API_ATTRS void LoseLeastSignificantDigit(); // with rounding
330331

331-
void PushCarry(int carry) {
332+
RT_API_ATTRS void PushCarry(int carry) {
332333
if (digits_ == maxDigits && RemoveLeastOrderZeroDigits() == 0) {
333334
LoseLeastSignificantDigit();
334335
digit_[digits_ - 1] += carry;
@@ -340,18 +341,20 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
340341
// Adds another number and then divides by two.
341342
// Assumes same exponent and sign.
342343
// Returns true when the result has effectively been rounded down.
343-
bool Mean(const BigRadixFloatingPointNumber &);
344+
RT_API_ATTRS bool Mean(const BigRadixFloatingPointNumber &);
344345

345346
// Parses a floating-point number; leaves the pointer reference
346347
// argument pointing at the next character after what was recognized.
347348
// The "end" argument can be left null if the caller is sure that the
348349
// string is properly terminated with an addressable character that
349350
// can't be in a valid floating-point character.
350-
bool ParseNumber(const char *&, bool &inexact, const char *end);
351+
RT_API_ATTRS bool ParseNumber(const char *&, bool &inexact, const char *end);
351352

352353
using Raw = typename Real::RawType;
353-
constexpr Raw SignBit() const { return Raw{isNegative_} << (Real::bits - 1); }
354-
constexpr Raw Infinity() const {
354+
constexpr RT_API_ATTRS Raw SignBit() const {
355+
return Raw{isNegative_} << (Real::bits - 1);
356+
}
357+
constexpr RT_API_ATTRS Raw Infinity() const {
355358
Raw result{static_cast<Raw>(Real::maxExponent)};
356359
result <<= Real::significandBits;
357360
result |= SignBit();
@@ -360,7 +363,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
360363
}
361364
return result;
362365
}
363-
constexpr Raw NaN(bool isQuiet = true) {
366+
constexpr RT_API_ATTRS Raw NaN(bool isQuiet = true) {
364367
Raw result{Real::maxExponent};
365368
result <<= Real::significandBits;
366369
result |= SignBit();
@@ -373,7 +376,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
373376
}
374377
return result;
375378
}
376-
constexpr Raw HUGE() const {
379+
constexpr RT_API_ATTRS Raw HUGE() const {
377380
Raw result{static_cast<Raw>(Real::maxExponent)};
378381
result <<= Real::significandBits;
379382
result |= SignBit();

flang/lib/Decimal/binary-to-decimal.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ template ConversionToDecimalResult ConvertToDecimal<113>(char *, std::size_t,
336336
BinaryFloatingPointNumber<113>);
337337

338338
extern "C" {
339+
RT_EXT_API_GROUP_BEGIN
340+
339341
ConversionToDecimalResult ConvertFloatToDecimal(char *buffer, std::size_t size,
340342
enum DecimalConversionFlags flags, int digits,
341343
enum FortranRounding rounding, float x) {
@@ -365,7 +367,9 @@ ConversionToDecimalResult ConvertLongDoubleToDecimal(char *buffer,
365367
rounding, Fortran::decimal::BinaryFloatingPointNumber<113>(x));
366368
}
367369
#endif
368-
}
370+
371+
RT_EXT_API_GROUP_END
372+
} // extern "C"
369373

370374
template <int PREC, int LOG10RADIX>
371375
template <typename STREAM>

flang/lib/Decimal/decimal-to-binary.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,12 @@ template <int PREC> class IntermediateFloat {
191191
static constexpr IntType topBit{IntType{1} << (precision - 1)};
192192
static constexpr IntType mask{topBit + (topBit - 1)};
193193

194-
IntermediateFloat() {}
194+
RT_API_ATTRS IntermediateFloat() {}
195195
IntermediateFloat(const IntermediateFloat &) = default;
196196

197197
// Assumes that exponent_ is valid on entry, and may increment it.
198198
// Returns the number of guard_ bits that have been determined.
199-
template <typename UINT> bool SetTo(UINT n) {
199+
template <typename UINT> RT_API_ATTRS bool SetTo(UINT n) {
200200
static constexpr int nBits{CHAR_BIT * sizeof n};
201201
if constexpr (precision >= nBits) {
202202
value_ = n;
@@ -218,14 +218,14 @@ template <int PREC> class IntermediateFloat {
218218
}
219219
}
220220

221-
void ShiftIn(int bit = 0) { value_ = value_ + value_ + bit; }
222-
bool IsFull() const { return value_ >= topBit; }
223-
void AdjustExponent(int by) { exponent_ += by; }
224-
void SetGuard(int g) {
221+
RT_API_ATTRS void ShiftIn(int bit = 0) { value_ = value_ + value_ + bit; }
222+
RT_API_ATTRS bool IsFull() const { return value_ >= topBit; }
223+
RT_API_ATTRS void AdjustExponent(int by) { exponent_ += by; }
224+
RT_API_ATTRS void SetGuard(int g) {
225225
guard_ |= (static_cast<GuardType>(g & 6) << (guardBits - 3)) | (g & 1);
226226
}
227227

228-
ConversionToBinaryResult<PREC> ToBinary(
228+
RT_API_ATTRS ConversionToBinaryResult<PREC> ToBinary(
229229
bool isNegative, FortranRounding) const;
230230

231231
private:
@@ -241,7 +241,7 @@ template <int PREC> class IntermediateFloat {
241241
// The standard says that these overflow cases round to "representable"
242242
// numbers, and some popular compilers interpret that to mean +/-HUGE()
243243
// rather than +/-Inf.
244-
static inline constexpr bool RoundOverflowToHuge(
244+
static inline RT_API_ATTRS constexpr bool RoundOverflowToHuge(
245245
enum FortranRounding rounding, bool isNegative) {
246246
return rounding == RoundToZero || (!isNegative && rounding == RoundDown) ||
247247
(isNegative && rounding == RoundUp);
@@ -531,6 +531,8 @@ template ConversionToBinaryResult<113> ConvertToBinary<113>(
531531
const char *&, enum FortranRounding, const char *end);
532532

533533
extern "C" {
534+
RT_EXT_API_GROUP_BEGIN
535+
534536
enum ConversionResultFlags ConvertDecimalToFloat(
535537
const char **p, float *f, enum FortranRounding rounding) {
536538
auto result{Fortran::decimal::ConvertToBinary<24>(*p, rounding)};
@@ -552,5 +554,7 @@ enum ConversionResultFlags ConvertDecimalToLongDouble(
552554
reinterpret_cast<const void *>(&result.binary), sizeof *ld);
553555
return result.flags;
554556
}
555-
}
557+
558+
RT_EXT_API_GROUP_END
559+
} // extern "C"
556560
} // namespace Fortran::decimal

0 commit comments

Comments
 (0)