/*
 * 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);

  // Emit code checking the status of the Marking Register, and aborting
  // the program if MR does not match the value stored in the art::Thread
  // object.
  //
  // Argument `temp` is used as a temporary register to generate code.
  // Argument `code` is used to identify the different occurrences of
  // MaybeGenerateMarkingRegisterCheck and is passed to the BKPT instruction.
  void GenerateMarkingRegisterCheck(vixl32::Register temp, int code = 0);

  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;
// Marking register declaration.
extern const vixl32::Register mr;

}  // namespace arm
}  // namespace art

#endif  // ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_VIXL_H_
