/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_SRC_GREENLAND_INTRINSIC_HELPER_H_
#define ART_SRC_GREENLAND_INTRINSIC_HELPER_H_

#include "base/logging.h"

#include <llvm/ADT/DenseMap.h>

namespace llvm {
  class Function;
  class FunctionType;
  class LLVMContext;
  class Module;
}  // namespace llvm

namespace art {
namespace llvm {

class IRBuilder;

class IntrinsicHelper {
 public:
  enum IntrinsicId {
#define DEF_INTRINSICS_FUNC(ID, ...) ID,
#include "intrinsic_func_list.def"
    MaxIntrinsicId,

    // Pseudo-intrinsics Id
    UnknownId
  };

  enum IntrinsicAttribute {
    kAttrNone     = 0,

    // Intrinsic that neither modified the memory state nor refer to the global
    // state
    kAttrReadNone = 1 << 0,

    // Intrinsic that doesn't modify the memory state. Note that one should set
    // this flag carefully when the intrinsic may throw exception. Since the
    // thread state is implicitly modified when an exception is thrown.
    kAttrReadOnly = 1 << 1,

    // Note that intrinsic without kAttrNoThrow and kAttrDoThrow set means that
    // intrinsic generates exception in some cases

    // Intrinsic that never generates exception
    kAttrNoThrow  = 1 << 2,
    // Intrinsic that always generate exception
    kAttrDoThrow  = 1 << 3,
  };

  enum IntrinsicValType {
    kNone,

    kVoidTy,

    kJavaObjectTy,
    kJavaMethodTy,
    kJavaThreadTy,

    kInt1Ty,
    kInt8Ty,
    kInt16Ty,
    kInt32Ty,
    kInt64Ty,
    kFloatTy,
    kDoubleTy,

    kInt1ConstantTy,
    kInt8ConstantTy,
    kInt16ConstantTy,
    kInt32ConstantTy,
    kInt64ConstantTy,
    kFloatConstantTy,
    kDoubleConstantTy,

    kVarArgTy,
  };

  enum {
    kIntrinsicMaxArgc = 5
  };

  typedef struct IntrinsicInfo {
    const char* name_;
    unsigned attr_;
    IntrinsicValType ret_val_type_;
    IntrinsicValType arg_type_[kIntrinsicMaxArgc];
  } IntrinsicInfo;

 private:
  static const IntrinsicInfo Info[];

 public:
  static const IntrinsicInfo& GetInfo(IntrinsicId id) {
    DCHECK(id >= 0 && id < MaxIntrinsicId) << "Unknown ART intrinsics ID: "
                                           << id;
    return Info[id];
  }

  static const char* GetName(IntrinsicId id) {
    return (id <= MaxIntrinsicId) ? GetInfo(id).name_ : "InvalidIntrinsic";
  }

  static unsigned GetAttr(IntrinsicId id) {
    return GetInfo(id).attr_;
  }

 public:
  IntrinsicHelper(::llvm::LLVMContext& context, ::llvm::Module& module);

  ::llvm::Function* GetIntrinsicFunction(IntrinsicId id) {
    DCHECK(id >= 0 && id < MaxIntrinsicId) << "Unknown ART intrinsics ID: "
                                           << id;
    return intrinsic_funcs_[id];
  }

  IntrinsicId GetIntrinsicId(const ::llvm::Function* func) const {
    ::llvm::DenseMap<const ::llvm::Function*, IntrinsicId>::const_iterator
        i = intrinsic_funcs_map_.find(func);
    if (i == intrinsic_funcs_map_.end()) {
      return UnknownId;
    } else {
      return i->second;
    }
  }

 private:
  // FIXME: "+1" is to workaround the GCC bugs:
  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
  // Remove this when uses newer GCC (> 4.4.3)
  ::llvm::Function* intrinsic_funcs_[MaxIntrinsicId + 1];

  // Map a llvm::Function to its intrinsic id
  ::llvm::DenseMap<const ::llvm::Function*, IntrinsicId> intrinsic_funcs_map_;
};

} // namespace llvm
} // namespace art

#endif // ART_SRC_GREENLAND_INTRINSIC_HELPER_H_
