1 //===- AMDILIntrinsicInfo.cpp - AMDIL Intrinsic Information ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //==-----------------------------------------------------------------------===//
10 // This file contains the AMDIL Implementation of the IntrinsicInfo class.
12 //===-----------------------------------------------------------------------===//
14 #include "AMDILIntrinsicInfo.h"
16 #include "AMDILTargetMachine.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Intrinsics.h"
19 #include "llvm/Module.h"
23 #define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
24 #include "AMDILGenIntrinsics.inc"
25 #undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
27 AMDILIntrinsicInfo::AMDILIntrinsicInfo(AMDILTargetMachine *tm)
28 : TargetIntrinsicInfo(), mTM(tm)
33 AMDILIntrinsicInfo::getName(unsigned int IntrID, Type **Tys,
34 unsigned int numTys) const
36 static const char* const names[] = {
37 #define GET_INTRINSIC_NAME_TABLE
38 #include "AMDILGenIntrinsics.inc"
39 #undef GET_INTRINSIC_NAME_TABLE
42 //assert(!isOverloaded(IntrID)
43 //&& "AMDIL Intrinsics are not overloaded");
44 if (IntrID < Intrinsic::num_intrinsics) {
47 assert(IntrID < AMDGPUIntrinsic::num_AMDIL_intrinsics
48 && "Invalid intrinsic ID");
50 std::string Result(names[IntrID - Intrinsic::num_intrinsics]);
55 checkTruncation(const char *Name, unsigned int& Len)
57 const char *ptr = Name + (Len - 1);
58 while(ptr != Name && *ptr != '_') {
61 // We don't want to truncate on atomic instructions
62 // but we do want to enter the check Truncation
63 // section so that we can translate the atomic
64 // instructions if we need to.
65 if (!strncmp(Name, "__atom", 6)) {
68 if (strstr(ptr, "i32")
77 || strstr(ptr, "u8")) {
78 Len = (unsigned int)(ptr - Name);
84 // We don't want to support both the OpenCL 1.0 atomics
85 // and the 1.1 atomics with different names, so we translate
86 // the 1.0 atomics to the 1.1 naming here if needed.
88 atomTranslateIfNeeded(const char *Name, unsigned int Len)
91 if (strncmp(Name, "__atom_", 7)) {
92 // If we are not starting with __atom_, then
93 // go ahead and continue on with the allocation.
94 buffer = new char[Len + 1];
95 memcpy(buffer, Name, Len);
97 buffer = new char[Len + 3];
98 memcpy(buffer, "__atomic_", 9);
99 memcpy(buffer + 9, Name + 7, Len - 7);
107 AMDILIntrinsicInfo::lookupName(const char *Name, unsigned int Len) const
109 #define GET_FUNCTION_RECOGNIZER
110 #include "AMDILGenIntrinsics.inc"
111 #undef GET_FUNCTION_RECOGNIZER
112 AMDGPUIntrinsic::ID IntrinsicID
113 = (AMDGPUIntrinsic::ID)Intrinsic::not_intrinsic;
114 if (checkTruncation(Name, Len)) {
115 char *buffer = atomTranslateIfNeeded(Name, Len);
116 IntrinsicID = getIntrinsicForGCCBuiltin("AMDIL", buffer);
119 IntrinsicID = getIntrinsicForGCCBuiltin("AMDIL", Name);
121 if (!isValidIntrinsic(IntrinsicID)) {
124 if (IntrinsicID != (AMDGPUIntrinsic::ID)Intrinsic::not_intrinsic) {
131 AMDILIntrinsicInfo::isOverloaded(unsigned id) const
134 #define GET_INTRINSIC_OVERLOAD_TABLE
135 #include "AMDILGenIntrinsics.inc"
136 #undef GET_INTRINSIC_OVERLOAD_TABLE
139 /// This defines the "getAttributes(ID id)" method.
140 #define GET_INTRINSIC_ATTRIBUTES
141 #include "AMDILGenIntrinsics.inc"
142 #undef GET_INTRINSIC_ATTRIBUTES
145 AMDILIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID,
147 unsigned numTys) const
149 assert(!isOverloaded(IntrID) && "AMDIL intrinsics are not overloaded");
150 AttrListPtr AList = getAttributes((AMDGPUIntrinsic::ID) IntrID);
151 LLVMContext& Context = M->getContext();
152 unsigned int id = IntrID;
153 Type *ResultTy = NULL;
154 std::vector<Type*> ArgTys;
155 bool IsVarArg = false;
157 #define GET_INTRINSIC_GENERATOR
158 #include "AMDILGenIntrinsics.inc"
159 #undef GET_INTRINSIC_GENERATOR
160 // We need to add the resource ID argument for atomics.
161 if (id >= AMDGPUIntrinsic::AMDIL_atomic_add_gi32
162 && id <= AMDGPUIntrinsic::AMDIL_atomic_xor_ru32_noret) {
163 ArgTys.push_back(IntegerType::get(Context, 32));
166 return cast<Function>(M->getOrInsertFunction(getName(IntrID),
167 FunctionType::get(ResultTy, ArgTys, IsVarArg),
171 /// Because the code generator has to support different SC versions,
172 /// this function is added to check that the intrinsic being used
173 /// is actually valid. In the case where it isn't valid, the
174 /// function call is not translated into an intrinsic and the
175 /// fall back software emulated path should pick up the result.
177 AMDILIntrinsicInfo::isValidIntrinsic(unsigned int IntrID) const
179 const AMDILSubtarget *stm = mTM->getSubtargetImpl();
183 case AMDGPUIntrinsic::AMDIL_convert_f32_i32_rpi:
184 case AMDGPUIntrinsic::AMDIL_convert_f32_i32_flr:
185 case AMDGPUIntrinsic::AMDIL_convert_f32_f16_near:
186 case AMDGPUIntrinsic::AMDIL_convert_f32_f16_neg_inf:
187 case AMDGPUIntrinsic::AMDIL_convert_f32_f16_plus_inf:
188 return stm->calVersion() >= CAL_VERSION_SC_139;