xref: /llvm-project/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp (revision f023da12d12635f5fba436e825cbfc999e28e623)
1529d0942SValentin Clement //===-- Numeric.cpp -- runtime API for numeric intrinsics -----------------===//
2529d0942SValentin Clement //
3529d0942SValentin Clement // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4529d0942SValentin Clement // See https://llvm.org/LICENSE.txt for license information.
5529d0942SValentin Clement // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6529d0942SValentin Clement //
7529d0942SValentin Clement //===----------------------------------------------------------------------===//
8529d0942SValentin Clement 
9529d0942SValentin Clement #include "flang/Optimizer/Builder/Runtime/Numeric.h"
10529d0942SValentin Clement #include "flang/Optimizer/Builder/BoxValue.h"
11529d0942SValentin Clement #include "flang/Optimizer/Builder/Character.h"
12529d0942SValentin Clement #include "flang/Optimizer/Builder/FIRBuilder.h"
13529d0942SValentin Clement #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
1404b18530SPete Steinfeld #include "flang/Optimizer/Support/Utils.h"
15529d0942SValentin Clement #include "flang/Runtime/numeric.h"
1623aa5a74SRiver Riddle #include "mlir/Dialect/Func/IR/FuncOps.h"
17529d0942SValentin Clement 
18529d0942SValentin Clement using namespace Fortran::runtime;
19529d0942SValentin Clement 
20529d0942SValentin Clement // The real*10 and real*16 placeholders below are used to force the
21529d0942SValentin Clement // compilation of the real*10 and real*16 method names on systems that
22529d0942SValentin Clement // may not have them in their runtime library. This can occur in the
23529d0942SValentin Clement // case of cross compilation, for example.
24529d0942SValentin Clement 
25a03e93e1SDavid Parks /// Placeholder for real*10 version of ErfcScaled Intrinsic
26a03e93e1SDavid Parks struct ForcedErfcScaled10 {
27a03e93e1SDavid Parks   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ErfcScaled10));
28a03e93e1SDavid Parks   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
29a03e93e1SDavid Parks     return [](mlir::MLIRContext *ctx) {
30*f023da12SMatthias Springer       auto ty = mlir::Float80Type::get(ctx);
31a03e93e1SDavid Parks       return mlir::FunctionType::get(ctx, {ty}, {ty});
32a03e93e1SDavid Parks     };
33a03e93e1SDavid Parks   }
34a03e93e1SDavid Parks };
35a03e93e1SDavid Parks 
36a03e93e1SDavid Parks /// Placeholder for real*16 version of ErfcScaled Intrinsic
37a03e93e1SDavid Parks struct ForcedErfcScaled16 {
38a03e93e1SDavid Parks   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ErfcScaled16));
39a03e93e1SDavid Parks   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
40a03e93e1SDavid Parks     return [](mlir::MLIRContext *ctx) {
41*f023da12SMatthias Springer       auto ty = mlir::Float128Type::get(ctx);
42a03e93e1SDavid Parks       return mlir::FunctionType::get(ctx, {ty}, {ty});
43a03e93e1SDavid Parks     };
44a03e93e1SDavid Parks   }
45a03e93e1SDavid Parks };
46a03e93e1SDavid Parks 
47529d0942SValentin Clement /// Placeholder for real*10 version of Exponent Intrinsic
48529d0942SValentin Clement struct ForcedExponent10_4 {
49529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Exponent10_4));
50529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
51529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
52*f023da12SMatthias Springer       auto fltTy = mlir::Float80Type::get(ctx);
53529d0942SValentin Clement       auto intTy = mlir::IntegerType::get(ctx, 32);
54529d0942SValentin Clement       return mlir::FunctionType::get(ctx, fltTy, intTy);
55529d0942SValentin Clement     };
56529d0942SValentin Clement   }
57529d0942SValentin Clement };
58529d0942SValentin Clement 
59529d0942SValentin Clement struct ForcedExponent10_8 {
60529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Exponent10_8));
61529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
62529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
63*f023da12SMatthias Springer       auto fltTy = mlir::Float80Type::get(ctx);
64529d0942SValentin Clement       auto intTy = mlir::IntegerType::get(ctx, 64);
65529d0942SValentin Clement       return mlir::FunctionType::get(ctx, fltTy, intTy);
66529d0942SValentin Clement     };
67529d0942SValentin Clement   }
68529d0942SValentin Clement };
69529d0942SValentin Clement 
70529d0942SValentin Clement /// Placeholder for real*16 version of Exponent Intrinsic
71529d0942SValentin Clement struct ForcedExponent16_4 {
72529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Exponent16_4));
73529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
74529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
75*f023da12SMatthias Springer       auto fltTy = mlir::Float128Type::get(ctx);
76529d0942SValentin Clement       auto intTy = mlir::IntegerType::get(ctx, 32);
77529d0942SValentin Clement       return mlir::FunctionType::get(ctx, fltTy, intTy);
78529d0942SValentin Clement     };
79529d0942SValentin Clement   }
80529d0942SValentin Clement };
81529d0942SValentin Clement 
82529d0942SValentin Clement struct ForcedExponent16_8 {
83529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Exponent16_8));
84529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
85529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
86*f023da12SMatthias Springer       auto fltTy = mlir::Float128Type::get(ctx);
87529d0942SValentin Clement       auto intTy = mlir::IntegerType::get(ctx, 64);
88529d0942SValentin Clement       return mlir::FunctionType::get(ctx, fltTy, intTy);
89529d0942SValentin Clement     };
90529d0942SValentin Clement   }
91529d0942SValentin Clement };
92529d0942SValentin Clement 
93529d0942SValentin Clement /// Placeholder for real*10 version of Fraction Intrinsic
94529d0942SValentin Clement struct ForcedFraction10 {
95529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Fraction10));
96529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
97529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
98*f023da12SMatthias Springer       auto ty = mlir::Float80Type::get(ctx);
99529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {ty}, {ty});
100529d0942SValentin Clement     };
101529d0942SValentin Clement   }
102529d0942SValentin Clement };
103529d0942SValentin Clement 
104529d0942SValentin Clement /// Placeholder for real*16 version of Fraction Intrinsic
105529d0942SValentin Clement struct ForcedFraction16 {
106529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Fraction16));
107529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
108529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
109*f023da12SMatthias Springer       auto ty = mlir::Float128Type::get(ctx);
110529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {ty}, {ty});
111529d0942SValentin Clement     };
112529d0942SValentin Clement   }
113529d0942SValentin Clement };
114529d0942SValentin Clement 
1151b9faafeSSlava Zakharin /// Placeholder for real*10 version of Mod Intrinsic
1161b9faafeSSlava Zakharin struct ForcedMod10 {
1171b9faafeSSlava Zakharin   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ModReal10));
1181b9faafeSSlava Zakharin   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
1191b9faafeSSlava Zakharin     return [](mlir::MLIRContext *ctx) {
120*f023da12SMatthias Springer       auto fltTy = mlir::Float80Type::get(ctx);
1211b9faafeSSlava Zakharin       auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
1221b9faafeSSlava Zakharin       auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
1231b9faafeSSlava Zakharin       return mlir::FunctionType::get(ctx, {fltTy, fltTy, strTy, intTy},
1241b9faafeSSlava Zakharin                                      {fltTy});
1251b9faafeSSlava Zakharin     };
1261b9faafeSSlava Zakharin   }
1271b9faafeSSlava Zakharin };
1281b9faafeSSlava Zakharin 
1291b9faafeSSlava Zakharin /// Placeholder for real*16 version of Mod Intrinsic
1301b9faafeSSlava Zakharin struct ForcedMod16 {
1311b9faafeSSlava Zakharin   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ModReal16));
1321b9faafeSSlava Zakharin   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
1331b9faafeSSlava Zakharin     return [](mlir::MLIRContext *ctx) {
134*f023da12SMatthias Springer       auto fltTy = mlir::Float128Type::get(ctx);
1351b9faafeSSlava Zakharin       auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
1361b9faafeSSlava Zakharin       auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
1371b9faafeSSlava Zakharin       return mlir::FunctionType::get(ctx, {fltTy, fltTy, strTy, intTy},
1381b9faafeSSlava Zakharin                                      {fltTy});
1391b9faafeSSlava Zakharin     };
1401b9faafeSSlava Zakharin   }
1411b9faafeSSlava Zakharin };
1421b9faafeSSlava Zakharin 
143315c88c5SSlava Zakharin /// Placeholder for real*10 version of Modulo Intrinsic
144315c88c5SSlava Zakharin struct ForcedModulo10 {
145315c88c5SSlava Zakharin   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ModuloReal10));
146315c88c5SSlava Zakharin   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
147315c88c5SSlava Zakharin     return [](mlir::MLIRContext *ctx) {
148*f023da12SMatthias Springer       auto fltTy = mlir::Float80Type::get(ctx);
149315c88c5SSlava Zakharin       auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
150315c88c5SSlava Zakharin       auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
151315c88c5SSlava Zakharin       return mlir::FunctionType::get(ctx, {fltTy, fltTy, strTy, intTy},
152315c88c5SSlava Zakharin                                      {fltTy});
153315c88c5SSlava Zakharin     };
154315c88c5SSlava Zakharin   }
155315c88c5SSlava Zakharin };
156315c88c5SSlava Zakharin 
15786293a7cSSlava Zakharin /// Placeholder for real*16 version of Modulo Intrinsic
15886293a7cSSlava Zakharin struct ForcedModulo16 {
15986293a7cSSlava Zakharin   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ModuloReal16));
16086293a7cSSlava Zakharin   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
16186293a7cSSlava Zakharin     return [](mlir::MLIRContext *ctx) {
162*f023da12SMatthias Springer       auto fltTy = mlir::Float128Type::get(ctx);
16386293a7cSSlava Zakharin       auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
16486293a7cSSlava Zakharin       auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
16586293a7cSSlava Zakharin       return mlir::FunctionType::get(ctx, {fltTy, fltTy, strTy, intTy},
16686293a7cSSlava Zakharin                                      {fltTy});
16786293a7cSSlava Zakharin     };
16886293a7cSSlava Zakharin   }
16986293a7cSSlava Zakharin };
17086293a7cSSlava Zakharin 
171529d0942SValentin Clement /// Placeholder for real*10 version of Nearest Intrinsic
172529d0942SValentin Clement struct ForcedNearest10 {
173529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Nearest10));
174529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
175529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
176*f023da12SMatthias Springer       auto fltTy = mlir::Float80Type::get(ctx);
177529d0942SValentin Clement       auto boolTy = mlir::IntegerType::get(ctx, 1);
178529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {fltTy, boolTy}, {fltTy});
179529d0942SValentin Clement     };
180529d0942SValentin Clement   }
181529d0942SValentin Clement };
182529d0942SValentin Clement 
183529d0942SValentin Clement /// Placeholder for real*16 version of Nearest Intrinsic
184529d0942SValentin Clement struct ForcedNearest16 {
185529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Nearest16));
186529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
187529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
188*f023da12SMatthias Springer       auto fltTy = mlir::Float128Type::get(ctx);
189529d0942SValentin Clement       auto boolTy = mlir::IntegerType::get(ctx, 1);
190529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {fltTy, boolTy}, {fltTy});
191529d0942SValentin Clement     };
192529d0942SValentin Clement   }
193529d0942SValentin Clement };
194529d0942SValentin Clement 
195529d0942SValentin Clement /// Placeholder for real*10 version of RRSpacing Intrinsic
196529d0942SValentin Clement struct ForcedRRSpacing10 {
197529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(RRSpacing10));
198529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
199529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
200*f023da12SMatthias Springer       auto ty = mlir::Float80Type::get(ctx);
201529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {ty}, {ty});
202529d0942SValentin Clement     };
203529d0942SValentin Clement   }
204529d0942SValentin Clement };
205529d0942SValentin Clement 
206529d0942SValentin Clement /// Placeholder for real*16 version of RRSpacing Intrinsic
207529d0942SValentin Clement struct ForcedRRSpacing16 {
208529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(RRSpacing16));
209529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
210529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
211*f023da12SMatthias Springer       auto ty = mlir::Float128Type::get(ctx);
212529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {ty}, {ty});
213529d0942SValentin Clement     };
214529d0942SValentin Clement   }
215529d0942SValentin Clement };
216529d0942SValentin Clement 
217529d0942SValentin Clement /// Placeholder for real*10 version of Scale Intrinsic
218529d0942SValentin Clement struct ForcedScale10 {
219529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Scale10));
220529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
221529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
222*f023da12SMatthias Springer       auto fltTy = mlir::Float80Type::get(ctx);
223529d0942SValentin Clement       auto intTy = mlir::IntegerType::get(ctx, 64);
224529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {fltTy, intTy}, {fltTy});
225529d0942SValentin Clement     };
226529d0942SValentin Clement   }
227529d0942SValentin Clement };
228529d0942SValentin Clement 
229529d0942SValentin Clement /// Placeholder for real*16 version of Scale Intrinsic
230529d0942SValentin Clement struct ForcedScale16 {
231529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Scale16));
232529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
233529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
234*f023da12SMatthias Springer       auto fltTy = mlir::Float128Type::get(ctx);
235529d0942SValentin Clement       auto intTy = mlir::IntegerType::get(ctx, 64);
236529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {fltTy, intTy}, {fltTy});
237529d0942SValentin Clement     };
238529d0942SValentin Clement   }
239529d0942SValentin Clement };
240529d0942SValentin Clement 
241529d0942SValentin Clement /// Placeholder for real*10 version of RRSpacing Intrinsic
242529d0942SValentin Clement struct ForcedSetExponent10 {
243529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SetExponent10));
244529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
245529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
246*f023da12SMatthias Springer       auto fltTy = mlir::Float80Type::get(ctx);
247529d0942SValentin Clement       auto intTy = mlir::IntegerType::get(ctx, 64);
248529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {fltTy, intTy}, {fltTy});
249529d0942SValentin Clement     };
250529d0942SValentin Clement   }
251529d0942SValentin Clement };
252529d0942SValentin Clement 
253529d0942SValentin Clement /// Placeholder for real*10 version of RRSpacing Intrinsic
254529d0942SValentin Clement struct ForcedSetExponent16 {
255529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SetExponent16));
256529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
257529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
258*f023da12SMatthias Springer       auto fltTy = mlir::Float128Type::get(ctx);
259529d0942SValentin Clement       auto intTy = mlir::IntegerType::get(ctx, 64);
260529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {fltTy, intTy}, {fltTy});
261529d0942SValentin Clement     };
262529d0942SValentin Clement   }
263529d0942SValentin Clement };
264529d0942SValentin Clement 
265529d0942SValentin Clement /// Placeholder for real*10 version of Spacing Intrinsic
266529d0942SValentin Clement struct ForcedSpacing10 {
267529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Spacing10));
268529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
269529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
270*f023da12SMatthias Springer       auto ty = mlir::Float80Type::get(ctx);
271529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {ty}, {ty});
272529d0942SValentin Clement     };
273529d0942SValentin Clement   }
274529d0942SValentin Clement };
275529d0942SValentin Clement 
276529d0942SValentin Clement /// Placeholder for real*16 version of Spacing Intrinsic
277529d0942SValentin Clement struct ForcedSpacing16 {
278529d0942SValentin Clement   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Spacing16));
279529d0942SValentin Clement   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
280529d0942SValentin Clement     return [](mlir::MLIRContext *ctx) {
281*f023da12SMatthias Springer       auto ty = mlir::Float128Type::get(ctx);
282529d0942SValentin Clement       return mlir::FunctionType::get(ctx, {ty}, {ty});
283529d0942SValentin Clement     };
284529d0942SValentin Clement   }
285529d0942SValentin Clement };
286529d0942SValentin Clement 
287922992a2SJay Foad /// Generate call to Exponent intrinsic runtime routine.
288529d0942SValentin Clement mlir::Value fir::runtime::genExponent(fir::FirOpBuilder &builder,
289529d0942SValentin Clement                                       mlir::Location loc, mlir::Type resultType,
290529d0942SValentin Clement                                       mlir::Value x) {
29158ceae95SRiver Riddle   mlir::func::FuncOp func;
292529d0942SValentin Clement   mlir::Type fltTy = x.getType();
29304b18530SPete Steinfeld   if (fltTy.isF32()) {
294529d0942SValentin Clement     if (resultType.isInteger(32))
295529d0942SValentin Clement       func = fir::runtime::getRuntimeFunc<mkRTKey(Exponent4_4)>(loc, builder);
296529d0942SValentin Clement     else if (resultType.isInteger(64))
297529d0942SValentin Clement       func = fir::runtime::getRuntimeFunc<mkRTKey(Exponent4_8)>(loc, builder);
298529d0942SValentin Clement   } else if (fltTy.isF64()) {
299529d0942SValentin Clement     if (resultType.isInteger(32))
300529d0942SValentin Clement       func = fir::runtime::getRuntimeFunc<mkRTKey(Exponent8_4)>(loc, builder);
301529d0942SValentin Clement     else if (resultType.isInteger(64))
302529d0942SValentin Clement       func = fir::runtime::getRuntimeFunc<mkRTKey(Exponent8_8)>(loc, builder);
303529d0942SValentin Clement   } else if (fltTy.isF80()) {
304529d0942SValentin Clement     if (resultType.isInteger(32))
305529d0942SValentin Clement       func = fir::runtime::getRuntimeFunc<ForcedExponent10_4>(loc, builder);
306529d0942SValentin Clement     else if (resultType.isInteger(64))
307529d0942SValentin Clement       func = fir::runtime::getRuntimeFunc<ForcedExponent10_8>(loc, builder);
308529d0942SValentin Clement   } else if (fltTy.isF128()) {
309529d0942SValentin Clement     if (resultType.isInteger(32))
310529d0942SValentin Clement       func = fir::runtime::getRuntimeFunc<ForcedExponent16_4>(loc, builder);
311529d0942SValentin Clement     else if (resultType.isInteger(64))
312529d0942SValentin Clement       func = fir::runtime::getRuntimeFunc<ForcedExponent16_8>(loc, builder);
313529d0942SValentin Clement   } else
31404b18530SPete Steinfeld     fir::intrinsicTypeTODO(builder, fltTy, loc, "EXPONENT");
315529d0942SValentin Clement 
3164a3460a7SRiver Riddle   auto funcTy = func.getFunctionType();
317529d0942SValentin Clement   llvm::SmallVector<mlir::Value> args = {
318529d0942SValentin Clement       builder.createConvert(loc, funcTy.getInput(0), x)};
319529d0942SValentin Clement 
320529d0942SValentin Clement   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
321529d0942SValentin Clement }
322529d0942SValentin Clement 
323922992a2SJay Foad /// Generate call to Fraction intrinsic runtime routine.
324529d0942SValentin Clement mlir::Value fir::runtime::genFraction(fir::FirOpBuilder &builder,
325529d0942SValentin Clement                                       mlir::Location loc, mlir::Value x) {
32658ceae95SRiver Riddle   mlir::func::FuncOp func;
327529d0942SValentin Clement   mlir::Type fltTy = x.getType();
32804b18530SPete Steinfeld   if (fltTy.isF32())
329529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(Fraction4)>(loc, builder);
330529d0942SValentin Clement   else if (fltTy.isF64())
331529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(Fraction8)>(loc, builder);
332529d0942SValentin Clement   else if (fltTy.isF80())
333529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedFraction10>(loc, builder);
334529d0942SValentin Clement   else if (fltTy.isF128())
335529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedFraction16>(loc, builder);
336529d0942SValentin Clement   else
33704b18530SPete Steinfeld     fir::intrinsicTypeTODO(builder, fltTy, loc, "FRACTION");
338529d0942SValentin Clement 
3394a3460a7SRiver Riddle   auto funcTy = func.getFunctionType();
340529d0942SValentin Clement   llvm::SmallVector<mlir::Value> args = {
341529d0942SValentin Clement       builder.createConvert(loc, funcTy.getInput(0), x)};
342529d0942SValentin Clement 
343529d0942SValentin Clement   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
344529d0942SValentin Clement }
345529d0942SValentin Clement 
3461b9faafeSSlava Zakharin /// Generate call to Mod intrinsic runtime routine.
3471b9faafeSSlava Zakharin mlir::Value fir::runtime::genMod(fir::FirOpBuilder &builder, mlir::Location loc,
3481b9faafeSSlava Zakharin                                  mlir::Value a, mlir::Value p) {
3491b9faafeSSlava Zakharin   mlir::func::FuncOp func;
3501b9faafeSSlava Zakharin   mlir::Type fltTy = a.getType();
3511b9faafeSSlava Zakharin 
3521b9faafeSSlava Zakharin   if (fltTy != p.getType())
3531b9faafeSSlava Zakharin     fir::emitFatalError(loc, "arguments type mismatch in MOD");
3541b9faafeSSlava Zakharin 
35504b18530SPete Steinfeld   if (fltTy.isF32())
3561b9faafeSSlava Zakharin     func = fir::runtime::getRuntimeFunc<mkRTKey(ModReal4)>(loc, builder);
3571b9faafeSSlava Zakharin   else if (fltTy.isF64())
3581b9faafeSSlava Zakharin     func = fir::runtime::getRuntimeFunc<mkRTKey(ModReal8)>(loc, builder);
3591b9faafeSSlava Zakharin   else if (fltTy.isF80())
3601b9faafeSSlava Zakharin     func = fir::runtime::getRuntimeFunc<ForcedMod10>(loc, builder);
3611b9faafeSSlava Zakharin   else if (fltTy.isF128())
3621b9faafeSSlava Zakharin     func = fir::runtime::getRuntimeFunc<ForcedMod16>(loc, builder);
3631b9faafeSSlava Zakharin   else
36404b18530SPete Steinfeld     fir::intrinsicTypeTODO(builder, fltTy, loc, "MOD");
3651b9faafeSSlava Zakharin 
3661b9faafeSSlava Zakharin   auto funcTy = func.getFunctionType();
3671b9faafeSSlava Zakharin   auto sourceFile = fir::factory::locationToFilename(builder, loc);
3681b9faafeSSlava Zakharin   auto sourceLine =
3691b9faafeSSlava Zakharin       fir::factory::locationToLineNo(builder, loc, funcTy.getInput(3));
3701b9faafeSSlava Zakharin   auto args = fir::runtime::createArguments(builder, loc, funcTy, a, p,
3711b9faafeSSlava Zakharin                                             sourceFile, sourceLine);
3721b9faafeSSlava Zakharin 
3731b9faafeSSlava Zakharin   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
3741b9faafeSSlava Zakharin }
3751b9faafeSSlava Zakharin 
37686293a7cSSlava Zakharin /// Generate call to Modulo intrinsic runtime routine.
37786293a7cSSlava Zakharin mlir::Value fir::runtime::genModulo(fir::FirOpBuilder &builder,
37886293a7cSSlava Zakharin                                     mlir::Location loc, mlir::Value a,
37986293a7cSSlava Zakharin                                     mlir::Value p) {
38086293a7cSSlava Zakharin   mlir::func::FuncOp func;
38186293a7cSSlava Zakharin   mlir::Type fltTy = a.getType();
38286293a7cSSlava Zakharin 
38386293a7cSSlava Zakharin   if (fltTy != p.getType())
38486293a7cSSlava Zakharin     fir::emitFatalError(loc, "arguments type mismatch in MOD");
38586293a7cSSlava Zakharin 
38686293a7cSSlava Zakharin   // MODULO is lowered into math operations in intrinsics lowering,
38786293a7cSSlava Zakharin   // so genModulo() should only be used for F128 data type now.
388315c88c5SSlava Zakharin   if (fltTy.isF32())
389315c88c5SSlava Zakharin     func = fir::runtime::getRuntimeFunc<mkRTKey(ModuloReal4)>(loc, builder);
390315c88c5SSlava Zakharin   else if (fltTy.isF64())
391315c88c5SSlava Zakharin     func = fir::runtime::getRuntimeFunc<mkRTKey(ModuloReal8)>(loc, builder);
392315c88c5SSlava Zakharin   else if (fltTy.isF80())
393315c88c5SSlava Zakharin     func = fir::runtime::getRuntimeFunc<ForcedModulo10>(loc, builder);
394315c88c5SSlava Zakharin   else if (fltTy.isF128())
39586293a7cSSlava Zakharin     func = fir::runtime::getRuntimeFunc<ForcedModulo16>(loc, builder);
39686293a7cSSlava Zakharin   else
39786293a7cSSlava Zakharin     fir::intrinsicTypeTODO(builder, fltTy, loc, "MODULO");
39886293a7cSSlava Zakharin 
39986293a7cSSlava Zakharin   auto funcTy = func.getFunctionType();
40086293a7cSSlava Zakharin   auto sourceFile = fir::factory::locationToFilename(builder, loc);
40186293a7cSSlava Zakharin   auto sourceLine =
40286293a7cSSlava Zakharin       fir::factory::locationToLineNo(builder, loc, funcTy.getInput(3));
40386293a7cSSlava Zakharin   auto args = fir::runtime::createArguments(builder, loc, funcTy, a, p,
40486293a7cSSlava Zakharin                                             sourceFile, sourceLine);
40586293a7cSSlava Zakharin 
40686293a7cSSlava Zakharin   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
40786293a7cSSlava Zakharin }
40886293a7cSSlava Zakharin 
4094cdc19b8Svdonaldson /// Generate call to Nearest intrinsic or a "Next" intrinsic module procedure.
410529d0942SValentin Clement mlir::Value fir::runtime::genNearest(fir::FirOpBuilder &builder,
411529d0942SValentin Clement                                      mlir::Location loc, mlir::Value x,
4124cdc19b8Svdonaldson                                      mlir::Value valueUp) {
41358ceae95SRiver Riddle   mlir::func::FuncOp func;
414529d0942SValentin Clement   mlir::Type fltTy = x.getType();
415529d0942SValentin Clement 
41604b18530SPete Steinfeld   if (fltTy.isF32())
417529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(Nearest4)>(loc, builder);
418529d0942SValentin Clement   else if (fltTy.isF64())
419529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(Nearest8)>(loc, builder);
420529d0942SValentin Clement   else if (fltTy.isF80())
421529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedNearest10>(loc, builder);
422529d0942SValentin Clement   else if (fltTy.isF128())
423529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedNearest16>(loc, builder);
424529d0942SValentin Clement   else
42504b18530SPete Steinfeld     fir::intrinsicTypeTODO(builder, fltTy, loc, "NEAREST");
426529d0942SValentin Clement 
4274a3460a7SRiver Riddle   auto funcTy = func.getFunctionType();
4284cdc19b8Svdonaldson   auto args = fir::runtime::createArguments(builder, loc, funcTy, x, valueUp);
429529d0942SValentin Clement 
430529d0942SValentin Clement   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
431529d0942SValentin Clement }
432529d0942SValentin Clement 
433529d0942SValentin Clement /// Generate call to RRSpacing intrinsic runtime routine.
434529d0942SValentin Clement mlir::Value fir::runtime::genRRSpacing(fir::FirOpBuilder &builder,
435529d0942SValentin Clement                                        mlir::Location loc, mlir::Value x) {
43658ceae95SRiver Riddle   mlir::func::FuncOp func;
437529d0942SValentin Clement   mlir::Type fltTy = x.getType();
438529d0942SValentin Clement 
43904b18530SPete Steinfeld   if (fltTy.isF32())
440529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(RRSpacing4)>(loc, builder);
441529d0942SValentin Clement   else if (fltTy.isF64())
442529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(RRSpacing8)>(loc, builder);
443529d0942SValentin Clement   else if (fltTy.isF80())
444529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedRRSpacing10>(loc, builder);
445529d0942SValentin Clement   else if (fltTy.isF128())
446529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedRRSpacing16>(loc, builder);
447529d0942SValentin Clement   else
44804b18530SPete Steinfeld     fir::intrinsicTypeTODO(builder, fltTy, loc, "RRSPACING");
449529d0942SValentin Clement 
4504a3460a7SRiver Riddle   auto funcTy = func.getFunctionType();
451529d0942SValentin Clement   llvm::SmallVector<mlir::Value> args = {
452529d0942SValentin Clement       builder.createConvert(loc, funcTy.getInput(0), x)};
453529d0942SValentin Clement 
454529d0942SValentin Clement   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
455529d0942SValentin Clement }
456529d0942SValentin Clement 
457a03e93e1SDavid Parks /// Generate call to ErfcScaled intrinsic runtime routine.
458a03e93e1SDavid Parks mlir::Value fir::runtime::genErfcScaled(fir::FirOpBuilder &builder,
459a03e93e1SDavid Parks                                         mlir::Location loc, mlir::Value x) {
460a03e93e1SDavid Parks   mlir::func::FuncOp func;
461a03e93e1SDavid Parks   mlir::Type fltTy = x.getType();
462a03e93e1SDavid Parks 
463a03e93e1SDavid Parks   if (fltTy.isF32())
464a03e93e1SDavid Parks     func = fir::runtime::getRuntimeFunc<mkRTKey(ErfcScaled4)>(loc, builder);
465a03e93e1SDavid Parks   else if (fltTy.isF64())
466a03e93e1SDavid Parks     func = fir::runtime::getRuntimeFunc<mkRTKey(ErfcScaled8)>(loc, builder);
467a03e93e1SDavid Parks   else if (fltTy.isF80())
468a03e93e1SDavid Parks     func = fir::runtime::getRuntimeFunc<ForcedErfcScaled10>(loc, builder);
469a03e93e1SDavid Parks   else if (fltTy.isF128())
470a03e93e1SDavid Parks     func = fir::runtime::getRuntimeFunc<ForcedErfcScaled16>(loc, builder);
471a03e93e1SDavid Parks   else
472a03e93e1SDavid Parks     fir::intrinsicTypeTODO(builder, fltTy, loc, "ERFC_SCALED");
473a03e93e1SDavid Parks 
474a03e93e1SDavid Parks   auto funcTy = func.getFunctionType();
475a03e93e1SDavid Parks   llvm::SmallVector<mlir::Value> args = {
476a03e93e1SDavid Parks       builder.createConvert(loc, funcTy.getInput(0), x)};
477a03e93e1SDavid Parks 
478a03e93e1SDavid Parks   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
479a03e93e1SDavid Parks }
480a03e93e1SDavid Parks 
481529d0942SValentin Clement /// Generate call to Scale intrinsic runtime routine.
482529d0942SValentin Clement mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
483529d0942SValentin Clement                                    mlir::Location loc, mlir::Value x,
484529d0942SValentin Clement                                    mlir::Value i) {
48558ceae95SRiver Riddle   mlir::func::FuncOp func;
486529d0942SValentin Clement   mlir::Type fltTy = x.getType();
487529d0942SValentin Clement 
48804b18530SPete Steinfeld   if (fltTy.isF32())
489529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(Scale4)>(loc, builder);
490529d0942SValentin Clement   else if (fltTy.isF64())
491529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(Scale8)>(loc, builder);
492529d0942SValentin Clement   else if (fltTy.isF80())
493529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedScale10>(loc, builder);
494529d0942SValentin Clement   else if (fltTy.isF128())
495529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedScale16>(loc, builder);
496529d0942SValentin Clement   else
49704b18530SPete Steinfeld     fir::intrinsicTypeTODO(builder, fltTy, loc, "SCALE");
498529d0942SValentin Clement 
4994a3460a7SRiver Riddle   auto funcTy = func.getFunctionType();
500529d0942SValentin Clement   auto args = fir::runtime::createArguments(builder, loc, funcTy, x, i);
501529d0942SValentin Clement 
502529d0942SValentin Clement   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
503529d0942SValentin Clement }
504529d0942SValentin Clement 
50566db7c60SValentin Clement (バレンタイン クレメン) /// Generate call to Selected_char_kind intrinsic runtime routine.
50666db7c60SValentin Clement (バレンタイン クレメン) mlir::Value fir::runtime::genSelectedCharKind(fir::FirOpBuilder &builder,
50766db7c60SValentin Clement (バレンタイン クレメン)                                               mlir::Location loc,
50866db7c60SValentin Clement (バレンタイン クレメン)                                               mlir::Value name,
50966db7c60SValentin Clement (バレンタイン クレメン)                                               mlir::Value length) {
51066db7c60SValentin Clement (バレンタイン クレメン)   mlir::func::FuncOp func =
51166db7c60SValentin Clement (バレンタイン クレメン)       fir::runtime::getRuntimeFunc<mkRTKey(SelectedCharKind)>(loc, builder);
51266db7c60SValentin Clement (バレンタイン クレメン)   auto fTy = func.getFunctionType();
51366db7c60SValentin Clement (バレンタイン クレメン)   auto sourceFile = fir::factory::locationToFilename(builder, loc);
51466db7c60SValentin Clement (バレンタイン クレメン)   auto sourceLine =
51566db7c60SValentin Clement (バレンタイン クレメン)       fir::factory::locationToLineNo(builder, loc, fTy.getInput(1));
51666db7c60SValentin Clement (バレンタイン クレメン)   if (!fir::isa_ref_type(name.getType()))
51766db7c60SValentin Clement (バレンタイン クレメン)     fir::emitFatalError(loc, "argument address for runtime not found");
51866db7c60SValentin Clement (バレンタイン クレメン) 
51966db7c60SValentin Clement (バレンタイン クレメン)   auto args = fir::runtime::createArguments(builder, loc, fTy, sourceFile,
52066db7c60SValentin Clement (バレンタイン クレメン)                                             sourceLine, name, length);
52166db7c60SValentin Clement (バレンタイン クレメン) 
52266db7c60SValentin Clement (バレンタイン クレメン)   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
52366db7c60SValentin Clement (バレンタイン クレメン) }
52466db7c60SValentin Clement (バレンタイン クレメン) 
525f532c072SPeixin Qiao /// Generate call to Selected_int_kind intrinsic runtime routine.
526f532c072SPeixin Qiao mlir::Value fir::runtime::genSelectedIntKind(fir::FirOpBuilder &builder,
527f532c072SPeixin Qiao                                              mlir::Location loc,
528f532c072SPeixin Qiao                                              mlir::Value x) {
529f532c072SPeixin Qiao   mlir::func::FuncOp func =
530f532c072SPeixin Qiao       fir::runtime::getRuntimeFunc<mkRTKey(SelectedIntKind)>(loc, builder);
531f532c072SPeixin Qiao   auto fTy = func.getFunctionType();
532f532c072SPeixin Qiao   auto sourceFile = fir::factory::locationToFilename(builder, loc);
533f532c072SPeixin Qiao   auto sourceLine =
534f532c072SPeixin Qiao       fir::factory::locationToLineNo(builder, loc, fTy.getInput(1));
535f532c072SPeixin Qiao   if (!fir::isa_ref_type(x.getType()))
536f532c072SPeixin Qiao     fir::emitFatalError(loc, "argument address for runtime not found");
537f532c072SPeixin Qiao   mlir::Type eleTy = fir::unwrapRefType(x.getType());
538f532c072SPeixin Qiao   mlir::Value xKind = builder.createIntegerConstant(
539f532c072SPeixin Qiao       loc, fTy.getInput(3), eleTy.getIntOrFloatBitWidth() / 8);
540f532c072SPeixin Qiao   auto args = fir::runtime::createArguments(builder, loc, fTy, sourceFile,
541f532c072SPeixin Qiao                                             sourceLine, x, xKind);
542f532c072SPeixin Qiao 
543f532c072SPeixin Qiao   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
544f532c072SPeixin Qiao }
545f532c072SPeixin Qiao 
546bdbf927aSValentin Clement (バレンタイン クレメン) /// Generate call to Selected_logical_kind intrinsic runtime routine.
547bdbf927aSValentin Clement (バレンタイン クレメン) mlir::Value fir::runtime::genSelectedLogicalKind(fir::FirOpBuilder &builder,
548bdbf927aSValentin Clement (バレンタイン クレメン)                                                  mlir::Location loc,
549bdbf927aSValentin Clement (バレンタイン クレメン)                                                  mlir::Value x) {
550bdbf927aSValentin Clement (バレンタイン クレメン)   mlir::func::FuncOp func =
551bdbf927aSValentin Clement (バレンタイン クレメン)       fir::runtime::getRuntimeFunc<mkRTKey(SelectedLogicalKind)>(loc, builder);
552bdbf927aSValentin Clement (バレンタイン クレメン)   auto fTy = func.getFunctionType();
553bdbf927aSValentin Clement (バレンタイン クレメン)   auto sourceFile = fir::factory::locationToFilename(builder, loc);
554bdbf927aSValentin Clement (バレンタイン クレメン)   auto sourceLine =
555bdbf927aSValentin Clement (バレンタイン クレメン)       fir::factory::locationToLineNo(builder, loc, fTy.getInput(1));
556bdbf927aSValentin Clement (バレンタイン クレメン)   if (!fir::isa_ref_type(x.getType()))
557bdbf927aSValentin Clement (バレンタイン クレメン)     fir::emitFatalError(loc, "argument address for runtime not found");
558bdbf927aSValentin Clement (バレンタイン クレメン)   mlir::Type eleTy = fir::unwrapRefType(x.getType());
559bdbf927aSValentin Clement (バレンタイン クレメン)   mlir::Value xKind = builder.createIntegerConstant(
560bdbf927aSValentin Clement (バレンタイン クレメン)       loc, fTy.getInput(3), eleTy.getIntOrFloatBitWidth() / 8);
561bdbf927aSValentin Clement (バレンタイン クレメン)   auto args = fir::runtime::createArguments(builder, loc, fTy, sourceFile,
562bdbf927aSValentin Clement (バレンタイン クレメン)                                             sourceLine, x, xKind);
563bdbf927aSValentin Clement (バレンタイン クレメン) 
564bdbf927aSValentin Clement (バレンタイン クレメン)   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
565bdbf927aSValentin Clement (バレンタイン クレメン) }
566bdbf927aSValentin Clement (バレンタイン クレメン) 
56757e3fa38SPeixin Qiao /// Generate call to Selected_real_kind intrinsic runtime routine.
56857e3fa38SPeixin Qiao mlir::Value fir::runtime::genSelectedRealKind(fir::FirOpBuilder &builder,
56957e3fa38SPeixin Qiao                                               mlir::Location loc,
57057e3fa38SPeixin Qiao                                               mlir::Value precision,
57157e3fa38SPeixin Qiao                                               mlir::Value range,
57257e3fa38SPeixin Qiao                                               mlir::Value radix) {
57357e3fa38SPeixin Qiao   mlir::func::FuncOp func =
57457e3fa38SPeixin Qiao       fir::runtime::getRuntimeFunc<mkRTKey(SelectedRealKind)>(loc, builder);
57557e3fa38SPeixin Qiao   auto fTy = func.getFunctionType();
57657e3fa38SPeixin Qiao   auto getArgKinds = [&](mlir::Value arg, int argKindIndex) -> mlir::Value {
57757e3fa38SPeixin Qiao     if (fir::isa_ref_type(arg.getType())) {
57857e3fa38SPeixin Qiao       mlir::Type eleTy = fir::unwrapRefType(arg.getType());
57957e3fa38SPeixin Qiao       return builder.createIntegerConstant(loc, fTy.getInput(argKindIndex),
58057e3fa38SPeixin Qiao                                            eleTy.getIntOrFloatBitWidth() / 8);
58157e3fa38SPeixin Qiao     } else {
58257e3fa38SPeixin Qiao       return builder.createIntegerConstant(loc, fTy.getInput(argKindIndex), 0);
58357e3fa38SPeixin Qiao     }
58457e3fa38SPeixin Qiao   };
58557e3fa38SPeixin Qiao 
58657e3fa38SPeixin Qiao   auto sourceFile = fir::factory::locationToFilename(builder, loc);
58757e3fa38SPeixin Qiao   auto sourceLine =
58857e3fa38SPeixin Qiao       fir::factory::locationToLineNo(builder, loc, fTy.getInput(1));
58957e3fa38SPeixin Qiao   mlir::Value pKind = getArgKinds(precision, 3);
59057e3fa38SPeixin Qiao   mlir::Value rKind = getArgKinds(range, 5);
59157e3fa38SPeixin Qiao   mlir::Value dKind = getArgKinds(radix, 7);
59257e3fa38SPeixin Qiao   auto args = fir::runtime::createArguments(builder, loc, fTy, sourceFile,
59357e3fa38SPeixin Qiao                                             sourceLine, precision, pKind, range,
59457e3fa38SPeixin Qiao                                             rKind, radix, dKind);
59557e3fa38SPeixin Qiao 
59657e3fa38SPeixin Qiao   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
59757e3fa38SPeixin Qiao }
59857e3fa38SPeixin Qiao 
599922992a2SJay Foad /// Generate call to Set_exponent intrinsic runtime routine.
600529d0942SValentin Clement mlir::Value fir::runtime::genSetExponent(fir::FirOpBuilder &builder,
601529d0942SValentin Clement                                          mlir::Location loc, mlir::Value x,
602529d0942SValentin Clement                                          mlir::Value i) {
60358ceae95SRiver Riddle   mlir::func::FuncOp func;
604529d0942SValentin Clement   mlir::Type fltTy = x.getType();
605529d0942SValentin Clement 
60604b18530SPete Steinfeld   if (fltTy.isF32())
607529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(SetExponent4)>(loc, builder);
608529d0942SValentin Clement   else if (fltTy.isF64())
609529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(SetExponent8)>(loc, builder);
610529d0942SValentin Clement   else if (fltTy.isF80())
611529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedSetExponent10>(loc, builder);
612529d0942SValentin Clement   else if (fltTy.isF128())
613529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedSetExponent16>(loc, builder);
614529d0942SValentin Clement   else
61504b18530SPete Steinfeld     fir::intrinsicTypeTODO(builder, fltTy, loc, "SET_EXPONENT");
616529d0942SValentin Clement 
6174a3460a7SRiver Riddle   auto funcTy = func.getFunctionType();
618529d0942SValentin Clement   auto args = fir::runtime::createArguments(builder, loc, funcTy, x, i);
619529d0942SValentin Clement 
620529d0942SValentin Clement   return builder.create<fir::CallOp>(loc, func, args).getResult(0);
621529d0942SValentin Clement }
622529d0942SValentin Clement 
623529d0942SValentin Clement /// Generate call to Spacing intrinsic runtime routine.
624529d0942SValentin Clement mlir::Value fir::runtime::genSpacing(fir::FirOpBuilder &builder,
625529d0942SValentin Clement                                      mlir::Location loc, mlir::Value x) {
62658ceae95SRiver Riddle   mlir::func::FuncOp func;
627529d0942SValentin Clement   mlir::Type fltTy = x.getType();
628775f7f1cSjeanPerier   // TODO: for f16/bf16, there are better alternatives that do not require
629775f7f1cSjeanPerier   // casting the argument (resp. result) to (resp. from) f32, but this requires
630775f7f1cSjeanPerier   // knowing that the target runtime has been compiled with std::float16_t or
631775f7f1cSjeanPerier   // std::bfloat16_t support, which is not an information available here for
632775f7f1cSjeanPerier   // now.
63304b18530SPete Steinfeld   if (fltTy.isF32())
634529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing4)>(loc, builder);
635529d0942SValentin Clement   else if (fltTy.isF64())
636529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing8)>(loc, builder);
637529d0942SValentin Clement   else if (fltTy.isF80())
638529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedSpacing10>(loc, builder);
639529d0942SValentin Clement   else if (fltTy.isF128())
640529d0942SValentin Clement     func = fir::runtime::getRuntimeFunc<ForcedSpacing16>(loc, builder);
641775f7f1cSjeanPerier   else if (fltTy.isF16())
642775f7f1cSjeanPerier     func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing2By4)>(loc, builder);
643775f7f1cSjeanPerier   else if (fltTy.isBF16())
644775f7f1cSjeanPerier     func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing3By4)>(loc, builder);
645529d0942SValentin Clement   else
64604b18530SPete Steinfeld     fir::intrinsicTypeTODO(builder, fltTy, loc, "SPACING");
647529d0942SValentin Clement 
6484a3460a7SRiver Riddle   auto funcTy = func.getFunctionType();
649529d0942SValentin Clement   llvm::SmallVector<mlir::Value> args = {
650529d0942SValentin Clement       builder.createConvert(loc, funcTy.getInput(0), x)};
651529d0942SValentin Clement 
652775f7f1cSjeanPerier   mlir::Value res = builder.create<fir::CallOp>(loc, func, args).getResult(0);
653775f7f1cSjeanPerier   return builder.createConvert(loc, fltTy, res);
654529d0942SValentin Clement }
655