/*
 * Copyright (C) 2014 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_COMPILER_UTILS_ARM64_ASSEMBLER_ARM64_H_
#define ART_COMPILER_UTILS_ARM64_ASSEMBLER_ARM64_H_

#include <stdint.h>
#include <memory>
#include <vector>

#include "base/arena_containers.h"
#include "base/logging.h"
#include "utils/arm64/managed_register_arm64.h"
#include "utils/assembler.h"
#include "offsets.h"

// TODO(VIXL): Make VIXL compile with -Wshadow.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#include "aarch64/disasm-aarch64.h"
#include "aarch64/macro-assembler-aarch64.h"
#pragma GCC diagnostic pop

namespace art {
namespace arm64 {

#define MEM_OP(...)      vixl::aarch64::MemOperand(__VA_ARGS__)

enum LoadOperandType {
  kLoadSignedByte,
  kLoadUnsignedByte,
  kLoadSignedHalfword,
  kLoadUnsignedHalfword,
  kLoadWord,
  kLoadCoreWord,
  kLoadSWord,
  kLoadDWord
};

enum StoreOperandType {
  kStoreByte,
  kStoreHalfword,
  kStoreWord,
  kStoreCoreWord,
  kStoreSWord,
  kStoreDWord
};

class Arm64Assembler FINAL : public Assembler {
 public:
  explicit Arm64Assembler(ArenaAllocator* arena) : Assembler(arena) {}

  virtual ~Arm64Assembler() {}

  vixl::aarch64::MacroAssembler* GetVIXLAssembler() { return &vixl_masm_; }

  // Finalize the code.
  void FinalizeCode() OVERRIDE;

  // Size of generated code.
  size_t CodeSize() const OVERRIDE;
  const uint8_t* CodeBufferBaseAddress() const OVERRIDE;

  // Copy instructions out of assembly buffer into the given region of memory.
  void FinalizeInstructions(const MemoryRegion& region);

  void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs);

  void SpillRegisters(vixl::aarch64::CPURegList registers, int offset);
  void UnspillRegisters(vixl::aarch64::CPURegList registers, int offset);

  // Jump to address (not setting link register)
  void JumpTo(ManagedRegister m_base, Offset offs, ManagedRegister m_scratch);

  //
  // Heap poisoning.
  //

  // Poison a heap reference contained in `reg`.
  void PoisonHeapReference(vixl::aarch64::Register reg);
  // Unpoison a heap reference contained in `reg`.
  void UnpoisonHeapReference(vixl::aarch64::Register reg);
  // Poison a heap reference contained in `reg` if heap poisoning is enabled.
  void MaybePoisonHeapReference(vixl::aarch64::Register reg);
  // Unpoison a heap reference contained in `reg` if heap poisoning is enabled.
  void MaybeUnpoisonHeapReference(vixl::aarch64::Register reg);

  void Bind(Label* label ATTRIBUTE_UNUSED) OVERRIDE {
    UNIMPLEMENTED(FATAL) << "Do not use Bind for ARM64";
  }
  void Jump(Label* label ATTRIBUTE_UNUSED) OVERRIDE {
    UNIMPLEMENTED(FATAL) << "Do not use Jump for ARM64";
  }

  static vixl::aarch64::Register reg_x(int code) {
    CHECK(code < kNumberOfXRegisters) << code;
    if (code == SP) {
      return vixl::aarch64::sp;
    } else if (code == XZR) {
      return vixl::aarch64::xzr;
    }
    return vixl::aarch64::Register::GetXRegFromCode(code);
  }

  static vixl::aarch64::Register reg_w(int code) {
    CHECK(code < kNumberOfWRegisters) << code;
    if (code == WSP) {
      return vixl::aarch64::wsp;
    } else if (code == WZR) {
      return vixl::aarch64::wzr;
    }
    return vixl::aarch64::Register::GetWRegFromCode(code);
  }

  static vixl::aarch64::FPRegister reg_d(int code) {
    return vixl::aarch64::FPRegister::GetDRegFromCode(code);
  }

  static vixl::aarch64::FPRegister reg_s(int code) {
    return vixl::aarch64::FPRegister::GetSRegFromCode(code);
  }

 private:
  // VIXL assembler.
  vixl::aarch64::MacroAssembler vixl_masm_;

  // Used for testing.
  friend class Arm64ManagedRegister_VixlRegisters_Test;
};

}  // namespace arm64
}  // namespace art

#endif  // ART_COMPILER_UTILS_ARM64_ASSEMBLER_ARM64_H_
