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