1//===-- MBlazeIntrinsicInfo.cpp - Intrinsic Information -------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the MBlaze implementation of TargetIntrinsicInfo.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MBlazeIntrinsicInfo.h"
15#include "llvm/IR/DerivedTypes.h"
16#include "llvm/IR/Function.h"
17#include "llvm/IR/Intrinsics.h"
18#include "llvm/IR/Module.h"
19#include "llvm/IR/Type.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/raw_ostream.h"
22#include <cstring>
23
24using namespace llvm;
25
26namespace mblazeIntrinsic {
27
28  enum ID {
29    last_non_mblaze_intrinsic = Intrinsic::num_intrinsics-1,
30#define GET_INTRINSIC_ENUM_VALUES
31#include "MBlazeGenIntrinsics.inc"
32#undef GET_INTRINSIC_ENUM_VALUES
33    , num_mblaze_intrinsics
34  };
35
36#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
37#include "MBlazeGenIntrinsics.inc"
38#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
39}
40
41std::string MBlazeIntrinsicInfo::getName(unsigned IntrID, Type **Tys,
42                                         unsigned numTys) const {
43  static const char *const names[] = {
44#define GET_INTRINSIC_NAME_TABLE
45#include "MBlazeGenIntrinsics.inc"
46#undef GET_INTRINSIC_NAME_TABLE
47  };
48
49  assert(!isOverloaded(IntrID) && "MBlaze intrinsics are not overloaded");
50  if (IntrID < Intrinsic::num_intrinsics)
51    return 0;
52  assert(IntrID < mblazeIntrinsic::num_mblaze_intrinsics &&
53         "Invalid intrinsic ID");
54
55  std::string Result(names[IntrID - Intrinsic::num_intrinsics]);
56  return Result;
57}
58
59unsigned MBlazeIntrinsicInfo::
60lookupName(const char *Name, unsigned Len) const {
61  if (Len < 5 || Name[4] != '.' || Name[0] != 'l' || Name[1] != 'l'
62      || Name[2] != 'v' || Name[3] != 'm')
63    return 0;  // All intrinsics start with 'llvm.'
64
65#define GET_FUNCTION_RECOGNIZER
66#include "MBlazeGenIntrinsics.inc"
67#undef GET_FUNCTION_RECOGNIZER
68  return 0;
69}
70
71unsigned MBlazeIntrinsicInfo::
72lookupGCCName(const char *Name) const {
73    return mblazeIntrinsic::getIntrinsicForGCCBuiltin("mblaze",Name);
74}
75
76bool MBlazeIntrinsicInfo::isOverloaded(unsigned IntrID) const {
77  if (IntrID == 0)
78    return false;
79
80  unsigned id = IntrID - Intrinsic::num_intrinsics + 1;
81#define GET_INTRINSIC_OVERLOAD_TABLE
82#include "MBlazeGenIntrinsics.inc"
83#undef GET_INTRINSIC_OVERLOAD_TABLE
84}
85
86/// This defines the "getAttributes(LLVMContext &C, ID id)" method.
87#define GET_INTRINSIC_ATTRIBUTES
88#include "MBlazeGenIntrinsics.inc"
89#undef GET_INTRINSIC_ATTRIBUTES
90
91static FunctionType *getType(LLVMContext &Context, unsigned id) {
92  Type *ResultTy = NULL;
93  SmallVector<Type*, 8> ArgTys;
94  bool IsVarArg = false;
95
96#define GET_INTRINSIC_GENERATOR
97#include "MBlazeGenIntrinsics.inc"
98#undef GET_INTRINSIC_GENERATOR
99
100  return FunctionType::get(ResultTy, ArgTys, IsVarArg);
101}
102
103Function *MBlazeIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID,
104                                                Type **Tys,
105                                                unsigned numTy) const {
106  assert(!isOverloaded(IntrID) && "MBlaze intrinsics are not overloaded");
107  AttributeSet AList = getAttributes(M->getContext(),
108                                    (mblazeIntrinsic::ID) IntrID);
109  return cast<Function>(M->getOrInsertFunction(getName(IntrID),
110                                               getType(M->getContext(), IntrID),
111                                               AList));
112}
113