/*
 * 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_IR_BUILDER_H_
#define ART_SRC_GREENLAND_IR_BUILDER_H_

#include "backend_types.h"
#include "intrinsic_helper.h"

#include "logging.h"

#include <llvm/Support/IRBuilder.h>
#include <llvm/Support/NoFolder.h>
#include <llvm/Metadata.h>

namespace llvm {
  class Module;
}

namespace art {
namespace greenland {

#if defined(ART_USE_QUICK_COMPILER)
class InserterWithDexOffset
   : public llvm::IRBuilderDefaultInserter<true> {
  public:
    InserterWithDexOffset() : node_(NULL) {}
    void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
                      llvm::BasicBlock *BB,
                      llvm::BasicBlock::iterator InsertPt) const {
      llvm::IRBuilderDefaultInserter<true>::InsertHelper(I, Name, BB, InsertPt);
      if (node_ != NULL) {
        I->setMetadata("DexOff", node_);
      }
    }
    void SetDexOffset(llvm::MDNode* node) {
      node_ = node;
    }
  private:
    llvm::MDNode* node_;
};

typedef llvm::IRBuilder<true, llvm::NoFolder, InserterWithDexOffset> LLVMIRBuilder;
#else
typedef llvm::IRBuilder<true> LLVMIRBuilder;
#endif

class IRBuilder : public LLVMIRBuilder {
 public:
  IRBuilder(llvm::LLVMContext& context, llvm::Module& module,
            IntrinsicHelper& intrinsic_helper);
  ~IRBuilder() { }

 public:
  //--------------------------------------------------------------------------
  // Pointer Arithmetic Helper Function
  //--------------------------------------------------------------------------
  llvm::IntegerType* GetPtrEquivIntTy() {
    return getInt32Ty();
  }

  llvm::ConstantInt* GetPtrEquivInt(int64_t i) {
    return llvm::ConstantInt::get(GetPtrEquivIntTy(), i);
  }

  //--------------------------------------------------------------------------
  // Intrinsic Helper Functions
  //--------------------------------------------------------------------------
  llvm::Function* GetIntrinsics(IntrinsicHelper::IntrinsicId instr_id) {
    return intrinsic_helper_.GetIntrinsicFunction(instr_id);
  }

  //--------------------------------------------------------------------------
  // Type Helper Functions
  //--------------------------------------------------------------------------
  llvm::Type* GetJType(char shorty_jty, JTypeSpace space) {
    return GetJType(GetJTypeFromShorty(shorty_jty), space);
  }

  llvm::Type* GetJType(JType jty, JTypeSpace space) {
    switch (space) {
    case kAccurate:
      return GetJTypeInAccurateSpace(jty);

    case kReg:
    case kField: // Currently field space is equivalent to register space.
      return GetJTypeInRegSpace(jty);

    case kArray:
      return GetJTypeInArraySpace(jty);
    }

    LOG(FATAL) << "Unknown type space: " << space;
    return NULL;
  }

  llvm::Type* GetJVoidTy() {
    return getVoidTy();
  }

  llvm::IntegerType* GetJBooleanTy() {
    return getInt1Ty();
  }

  llvm::IntegerType* GetJByteTy() {
    return getInt8Ty();
  }

  llvm::IntegerType* GetJCharTy() {
    return getInt16Ty();
  }

  llvm::IntegerType* GetJShortTy() {
    return getInt16Ty();
  }

  llvm::IntegerType* GetJIntTy() {
    return getInt32Ty();
  }

  llvm::IntegerType* GetJLongTy() {
    return getInt64Ty();
  }

  llvm::Type* GetJFloatTy() {
    return getFloatTy();
  }

  llvm::Type* GetJDoubleTy() {
    return getDoubleTy();
  }

  llvm::PointerType* GetJObjectTy() {
    return java_object_type_;
  }

  llvm::PointerType* GetJMethodTy() {
    return java_method_type_;
  }

  llvm::PointerType* GetJThreadTy() {
    return java_thread_type_;
  }

  //--------------------------------------------------------------------------
  // Constant Value Helper Function
  //--------------------------------------------------------------------------
  llvm::ConstantInt* GetJBoolean(bool is_true) {
    return (is_true) ? getTrue() : getFalse();
  }

  llvm::ConstantInt* GetJByte(int8_t i) {
    return llvm::ConstantInt::getSigned(GetJByteTy(), i);
  }

  llvm::ConstantInt* GetJChar(int16_t i) {
    return llvm::ConstantInt::getSigned(GetJCharTy(), i);
  }

  llvm::ConstantInt* GetJShort(int16_t i) {
    return llvm::ConstantInt::getSigned(GetJShortTy(), i);
  }

  llvm::ConstantInt* GetJInt(int32_t i) {
    return llvm::ConstantInt::getSigned(GetJIntTy(), i);
  }

  llvm::ConstantInt* GetJLong(int64_t i) {
    return llvm::ConstantInt::getSigned(GetJLongTy(), i);
  }

  llvm::Constant* GetJFloat(float f) {
    return llvm::ConstantFP::get(GetJFloatTy(), f);
  }

  llvm::Constant* GetJDouble(double d) {
    return llvm::ConstantFP::get(GetJDoubleTy(), d);
  }

  llvm::ConstantPointerNull* GetJNull() {
    return llvm::ConstantPointerNull::get(GetJObjectTy());
  }

  llvm::Constant* GetJZero(char shorty_jty) {
    return GetJZero(GetJTypeFromShorty(shorty_jty));
  }

  llvm::Constant* GetJZero(JType jty) {
    switch (jty) {
    case kVoid:
      LOG(FATAL) << "Zero is not a value of void type";
      return NULL;

    case kBoolean:
      return GetJBoolean(false);

    case kByte:
      return GetJByte(0);

    case kChar:
      return GetJChar(0);

    case kShort:
      return GetJShort(0);

    case kInt:
      return GetJInt(0);

    case kLong:
      return GetJLong(0);

    case kFloat:
      return GetJFloat(0.0f);

    case kDouble:
      return GetJDouble(0.0);

    case kObject:
      return GetJNull();

    default:
      LOG(FATAL) << "Unknown java type: " << jty;
      return NULL;
    }
  }

 private:
  llvm::Type* GetJTypeInAccurateSpace(JType jty);
  llvm::Type* GetJTypeInRegSpace(JType jty);
  llvm::Type* GetJTypeInArraySpace(JType jty);

  llvm::PointerType* java_object_type_;
  llvm::PointerType* java_method_type_;
  llvm::PointerType* java_thread_type_;

  IntrinsicHelper& intrinsic_helper_;
};

} // namespace greenland
} // namespace art

#endif // ART_SRC_GREENLAND_IR_BUILDER_H_
