xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/RuntimeLibcalls.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- RuntimeLibcalls.h - Interface for runtime libcalls -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements a common interface to work with library calls into a
10 // runtime that may be emitted by a given backend.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_IR_RUNTIME_LIBCALLS_H
15 #define LLVM_IR_RUNTIME_LIBCALLS_H
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/IR/CallingConv.h"
19 #include "llvm/Support/AtomicOrdering.h"
20 #include "llvm/TargetParser/Triple.h"
21 
22 namespace llvm {
23 namespace RTLIB {
24 
25 /// RTLIB::Libcall enum - This enum defines all of the runtime library calls
26 /// the backend can emit.  The various long double types cannot be merged,
27 /// because 80-bit library functions use "xf" and 128-bit use "tf".
28 ///
29 /// When adding PPCF128 functions here, note that their names generally need
30 /// to be overridden for Darwin with the xxx$LDBL128 form.  See
31 /// PPCISelLowering.cpp.
32 ///
33 enum Libcall {
34 #define HANDLE_LIBCALL(code, name) code,
35 #include "llvm/IR/RuntimeLibcalls.def"
36 #undef HANDLE_LIBCALL
37 };
38 
39 /// A simple container for information about the supported runtime calls.
40 struct RuntimeLibcallsInfo {
RuntimeLibcallsInfoRuntimeLibcallsInfo41   explicit RuntimeLibcallsInfo(const Triple &TT) {
42     initLibcalls(TT);
43   }
44 
45   /// Rename the default libcall routine name for the specified libcall.
setLibcallNameRuntimeLibcallsInfo46   void setLibcallName(RTLIB::Libcall Call, const char *Name) {
47     LibcallRoutineNames[Call] = Name;
48   }
49 
setLibcallNameRuntimeLibcallsInfo50   void setLibcallName(ArrayRef<RTLIB::Libcall> Calls, const char *Name) {
51     for (auto Call : Calls)
52       setLibcallName(Call, Name);
53   }
54 
55   /// Get the libcall routine name for the specified libcall.
getLibcallNameRuntimeLibcallsInfo56   const char *getLibcallName(RTLIB::Libcall Call) const {
57     return LibcallRoutineNames[Call];
58   }
59 
60   /// Set the CallingConv that should be used for the specified libcall.
setLibcallCallingConvRuntimeLibcallsInfo61   void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
62     LibcallCallingConvs[Call] = CC;
63   }
64 
65   /// Get the CallingConv that should be used for the specified libcall.
getLibcallCallingConvRuntimeLibcallsInfo66   CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
67     return LibcallCallingConvs[Call];
68   }
69 
getLibcallNamesRuntimeLibcallsInfo70   iterator_range<const char **> getLibcallNames() {
71     return llvm::make_range(LibcallRoutineNames,
72                             LibcallRoutineNames + RTLIB::UNKNOWN_LIBCALL);
73   }
74 
75 private:
76   /// Stores the name each libcall.
77   const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
78 
79   /// Stores the CallingConv that should be used for each libcall.
80   CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL];
81 
darwinHasSinCosRuntimeLibcallsInfo82   static bool darwinHasSinCos(const Triple &TT) {
83     assert(TT.isOSDarwin() && "should be called with darwin triple");
84     // Don't bother with 32 bit x86.
85     if (TT.getArch() == Triple::x86)
86       return false;
87     // Macos < 10.9 has no sincos_stret.
88     if (TT.isMacOSX())
89       return !TT.isMacOSXVersionLT(10, 9) && TT.isArch64Bit();
90     // iOS < 7.0 has no sincos_stret.
91     if (TT.isiOS())
92       return !TT.isOSVersionLT(7, 0);
93     // Any other darwin such as WatchOS/TvOS is new enough.
94     return true;
95   }
96 
97   /// Set default libcall names. If a target wants to opt-out of a libcall it
98   /// should be placed here.
99   void initLibcalls(const Triple &TT);
100 };
101 
102 } // namespace RTLIB
103 } // namespace llvm
104 
105 #endif // LLVM_IR_RUNTIME_LIBCALLS_H
106