/*
 * Copyright (C) 2016 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_ARM_ASSEMBLER_ARM_VIXL_H_
#define ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_VIXL_H_

#include "base/arena_containers.h"
#include "base/logging.h"
#include "constants_arm.h"
#include "offsets.h"
#include "utils/arm/assembler_arm_shared.h"
#include "utils/arm/managed_register_arm.h"
#include "utils/assembler.h"
#include "utils/jni_macro_assembler.h"

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

namespace vixl32 = vixl::aarch32;

namespace art {
namespace arm {

class ArmVIXLMacroAssembler FINAL : public vixl32::MacroAssembler {
 public:
  // Most methods fit in a 1KB code buffer, which results in more optimal alloc/realloc and
  // fewer system calls than a larger default capacity.
  static constexpr size_t kDefaultCodeBufferCapacity = 1 * KB;

  ArmVIXLMacroAssembler()
      : vixl32::MacroAssembler(ArmVIXLMacroAssembler::kDefaultCodeBufferCapacity) {}

  // The following interfaces can generate CMP+Bcc or Cbz/Cbnz.
  // CMP+Bcc are generated by default.
  // If a hint is given (is_far_target = false) and rn and label can all fit into Cbz/Cbnz,
  // then Cbz/Cbnz is generated.
  // Prefer following interfaces to using vixl32::MacroAssembler::Cbz/Cbnz.
  // In T32, Cbz/Cbnz instructions have following limitations:
  // - Far targets, which are over 126 bytes away, are not supported.
  // - Only low registers can be encoded.
  // - Backward branches are not supported.
  void CompareAndBranchIfZero(vixl32::Register rn,
                              vixl32::Label* label,
                              bool is_far_target = true);
  void CompareAndBranchIfNonZero(vixl32::Register rn,
                                 vixl32::Label* label,
                                 bool is_far_target = true);

  // In T32 some of the instructions (add, mov, etc) outside an IT block
  // have only 32-bit encodings. But there are 16-bit flag setting
  // versions of these instructions (adds, movs, etc). In most of the
  // cases in ART we don't care if the instructions keep flags or not;
  // thus we can benefit from smaller code size.
  // VIXL will never generate flag setting versions (for example, adds
  // for Add macro instruction) unless vixl32::DontCare option is
  // explicitly specified. That's why we introduce wrappers to use
  // DontCare option by default.
#define WITH_FLAGS_DONT_CARE_RD_RN_OP(func_name) \
  void (func_name)(vixl32::Register rd, vixl32::Register rn, const vixl32::Operand& operand) { \
    MacroAssembler::func_name(vixl32::DontCare, rd, rn, operand); \
  } \
  using MacroAssembler::func_name

  WITH_FLAGS_DONT_CARE_RD_RN_OP(Adc);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Sub);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Sbc);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Rsb);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Rsc);

  WITH_FLAGS_DONT_CARE_RD_RN_OP(Eor);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Orr);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Orn);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(And);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Bic);

  WITH_FLAGS_DONT_CARE_RD_RN_OP(Asr);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Lsr);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Lsl);
  WITH_FLAGS_DONT_CARE_RD_RN_OP(Ror);

#undef WITH_FLAGS_DONT_CARE_RD_RN_OP

#define WITH_FLAGS_DONT_CARE_RD_OP(func_name) \
  void (func_name)(vixl32::Register rd, const vixl32::Operand& operand) { \
    MacroAssembler::func_name(vixl32::DontCare, rd, operand); \
  } \
  using MacroAssembler::func_name

  WITH_FLAGS_DONT_CARE_RD_OP(Mvn);
  WITH_FLAGS_DONT_CARE_RD_OP(Mov);

#undef WITH_FLAGS_DONT_CARE_RD_OP

  // The following two functions don't fall into above categories. Overload them separately.
  void Rrx(vixl32::Register rd, vixl32::Register rn) {
    MacroAssembler::Rrx(vixl32::DontCare, rd, rn);
  }
  using MacroAssembler::Rrx;

  void Mul(vixl32::Register rd, vixl32::Register rn, vixl32::Register rm) {
    MacroAssembler::Mul(vixl32::DontCare, rd, rn, rm);
  }
  using MacroAssembler::Mul;

  // TODO: Remove when MacroAssembler::Add(FlagsUpdate, Condition, Register, Register, Operand)
  // makes the right decision about 16-bit encodings.
  void Add(vixl32::Register rd, vixl32::Register rn, const vixl32::Operand& operand) {
    if (rd.Is(rn) && operand.IsPlainRegister()) {
      MacroAssembler::Add(rd, rn, operand);
    } else {
      MacroAssembler::Add(vixl32::DontCare, rd, rn, operand);
    }
  }
  using MacroAssembler::Add;

  // These interfaces try to use 16-bit T2 encoding of B instruction.
  void B(vixl32::Label* label);
  // For B(label), we always try to use Narrow encoding, because 16-bit T2 encoding supports
  // jumping within 2KB range. For B(cond, label), because the supported branch range is 256
  // bytes; we use the far_target hint to try to use 16-bit T1 encoding for short range jumps.
  void B(vixl32::Condition cond, vixl32::Label* label, bool is_far_target = true);

  // Use literal for generating double constant if it doesn't fit VMOV encoding.
  void Vmov(vixl32::DRegister rd, double imm) {
    if (vixl::VFP::IsImmFP64(imm)) {
      MacroAssembler::Vmov(rd, imm);
    } else {
      MacroAssembler::Vldr(rd, imm);
    }
  }
  using MacroAssembler::Vmov;
};

class ArmVIXLAssembler FINAL : public Assembler {
 private:
  class ArmException;
 public:
  explicit ArmVIXLAssembler(ArenaAllocator* arena)
      : Assembler(arena) {
    // Use Thumb2 instruction set.
    vixl_masm_.UseT32();
  }

  virtual ~ArmVIXLAssembler() {}
  ArmVIXLMacroAssembler* GetVIXLAssembler() { return &vixl_masm_; }
  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) OVERRIDE;

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

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

  void StoreToOffset(StoreOperandType type,
                     vixl32::Register reg,
                     vixl32::Register base,
                     int32_t offset);
  void StoreSToOffset(vixl32::SRegister source, vixl32::Register base, int32_t offset);
  void StoreDToOffset(vixl32::DRegister source, vixl32::Register base, int32_t offset);

  void LoadImmediate(vixl32::Register dest, int32_t value);
  void LoadFromOffset(LoadOperandType type,
                      vixl32::Register reg,
                      vixl32::Register base,
                      int32_t offset);
  void LoadSFromOffset(vixl32::SRegister reg, vixl32::Register base, int32_t offset);
  void LoadDFromOffset(vixl32::DRegister reg, vixl32::Register base, int32_t offset);

  void LoadRegisterList(RegList regs, size_t stack_offset);
  void StoreRegisterList(RegList regs, size_t stack_offset);

  bool ShifterOperandCanAlwaysHold(uint32_t immediate);
  bool ShifterOperandCanHold(Opcode opcode, uint32_t immediate, SetCc set_cc = kCcDontCare);
  bool CanSplitLoadStoreOffset(int32_t allowed_offset_bits,
                               int32_t offset,
                               /*out*/ int32_t* add_to_base,
                               /*out*/ int32_t* offset_for_load_store);
  int32_t AdjustLoadStoreOffset(int32_t allowed_offset_bits,
                                vixl32::Register temp,
                                vixl32::Register base,
                                int32_t offset);
  int32_t GetAllowedLoadOffsetBits(LoadOperandType type);
  int32_t GetAllowedStoreOffsetBits(StoreOperandType type);

  void AddConstant(vixl32::Register rd, int32_t value);
  void AddConstant(vixl32::Register rd, vixl32::Register rn, int32_t value);
  void AddConstantInIt(vixl32::Register rd,
                       vixl32::Register rn,
                       int32_t value,
                       vixl32::Condition cond = vixl32::al);

  template <typename T>
  vixl::aarch32::Literal<T>* CreateLiteralDestroyedWithPool(T value) {
    vixl::aarch32::Literal<T>* literal =
        new vixl::aarch32::Literal<T>(value,
                                      vixl32::RawLiteral::kPlacedWhenUsed,
                                      vixl32::RawLiteral::kDeletedOnPoolDestruction);
    return literal;
  }

 private:
  // VIXL assembler.
  ArmVIXLMacroAssembler vixl_masm_;
};

// Thread register declaration.
extern const vixl32::Register tr;

}  // namespace arm
}  // namespace art

#endif  // ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_VIXL_H_
